fusenapi/server/websocket/internal/logic/ws_reuse_last_connect.go

80 lines
2.3 KiB
Go
Raw Normal View History

2023-08-15 10:14:44 +00:00
package logic
2023-08-23 07:08:45 +00:00
//复用websocket连接标识
2023-08-15 10:14:44 +00:00
import (
"encoding/json"
2023-08-18 09:33:42 +00:00
"fmt"
2023-08-15 10:14:44 +00:00
"fusenapi/constants"
2023-08-23 08:45:01 +00:00
"fusenapi/utils/encryption_decryption"
2023-08-15 10:14:44 +00:00
"github.com/zeromicro/go-zero/core/logx"
)
2023-08-30 09:40:40 +00:00
// 复用连接处理器
2023-08-30 09:46:47 +00:00
type reuseConnProcessor struct {
2023-08-30 09:40:40 +00:00
}
2023-08-30 10:51:24 +00:00
// 处理分发到这里的数据
2023-08-30 10:31:20 +00:00
func (r *reuseConnProcessor) allocationMessage(w *wsConnectItem, data []byte) {
2023-08-15 10:14:44 +00:00
logx.Info("收到请求恢复上次连接标识数据:", string(data))
2023-08-24 09:23:41 +00:00
var wid string
if err := json.Unmarshal(data, &wid); err != nil {
logx.Error(" invalid format of wid :", wid)
2023-08-30 10:31:20 +00:00
w.incomeDataFormatErrResponse("invalid format of wid")
2023-08-15 10:14:44 +00:00
return
}
2023-08-23 08:45:01 +00:00
//解密
2023-08-24 09:23:41 +00:00
decryptionWid, err := encryption_decryption.CBCDecrypt(wid)
2023-08-23 08:45:01 +00:00
if err != nil {
2023-08-30 10:31:20 +00:00
w.reuseLastConnErrResponse("invalid wid")
2023-08-15 10:14:44 +00:00
return
}
2023-08-24 09:23:41 +00:00
lendecryptionWid := len(decryptionWid)
2023-08-15 10:38:33 +00:00
//合成client后缀,不是同个后缀的不能复用
2023-08-30 10:31:20 +00:00
userPart := getUserJoinPart(w.userId, w.guestId, w.userAgent)
2023-08-15 10:38:33 +00:00
lenUserPart := len(userPart)
2023-08-24 09:23:41 +00:00
if lendecryptionWid <= lenUserPart {
2023-08-30 10:31:20 +00:00
w.reuseLastConnErrResponse("length of client id is to short")
2023-08-15 10:38:33 +00:00
return
}
//尾部不同不能复用
2023-08-24 09:23:41 +00:00
if decryptionWid[lendecryptionWid-lenUserPart:] != userPart {
2023-08-30 10:31:20 +00:00
w.reuseLastConnErrResponse("the client id is not belong to you before")
2023-08-15 10:38:33 +00:00
return
}
2023-08-15 10:14:44 +00:00
//存在是不能给他申请重新绑定
2023-08-24 09:23:41 +00:00
if v, ok := mapConnPool.Load(wid); ok {
2023-08-18 03:05:18 +00:00
obj, ok := v.(wsConnectItem)
if !ok {
2023-08-30 10:31:20 +00:00
w.reuseLastConnErrResponse("连接断言失败")
2023-08-18 03:05:18 +00:00
logx.Error("连接断言失败")
2023-08-30 10:31:20 +00:00
return
2023-08-18 03:05:18 +00:00
}
2023-08-24 06:11:17 +00:00
//是当前自己占用(无需处理)
2023-08-30 10:31:20 +00:00
if obj.uniqueId == w.uniqueId {
rsp := w.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, wid)
w.sendToOutChan(rsp)
2023-08-18 03:05:18 +00:00
return
} else {
2023-08-30 10:31:20 +00:00
w.reuseLastConnErrResponse("the wid is used by other people")
2023-08-18 03:05:18 +00:00
return
}
2023-08-15 10:14:44 +00:00
}
//重新绑定
2023-09-01 08:19:23 +00:00
logx.Info("开始重新绑定websocket连接标识")
2023-09-04 06:44:35 +00:00
oldUniqueId := w.uniqueId
2023-08-30 10:31:20 +00:00
w.uniqueId = wid
mapConnPool.Store(wid, *w)
2023-09-04 06:44:35 +00:00
//删除用户id级别之前的索引
deleteUserConnPoolElement(w.userId, w.guestId, oldUniqueId)
2023-09-04 03:21:24 +00:00
//添加用户id级别索引
2023-09-04 03:37:04 +00:00
createUserConnPoolElement(w.userId, w.guestId, wid)
2023-08-30 10:31:20 +00:00
rsp := w.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, wid)
w.sendToOutChan(rsp)
2023-09-01 08:19:23 +00:00
logx.Info("重新绑定websocket连接标识成功")
2023-08-15 10:14:44 +00:00
}
2023-08-18 09:33:42 +00:00
// 获取用户拼接部分(复用标识用到)
2023-08-30 03:25:20 +00:00
func getUserJoinPart(userId, guestId int64, userAgent string) string {
return fmt.Sprintf("|_%d_%d_|_%s_|", userId, guestId, userAgent)
2023-08-18 09:33:42 +00:00
}