fusenapi/server/websocket/internal/logic/ws_reuse_last_connect.go
laodaming a9b8df41f7 fix
2023-08-30 18:00:26 +08:00

72 lines
2.0 KiB
Go

package logic
//复用websocket连接标识
import (
"encoding/json"
"fmt"
"fusenapi/constants"
"fusenapi/utils/encryption_decryption"
"github.com/zeromicro/go-zero/core/logx"
)
// 复用连接处理器
type reuseConnProcessor struct {
w wsConnectItem
}
func (r *reuseConnProcessor) allocationMessage(data []byte) {
logx.Info("收到请求恢复上次连接标识数据:", string(data))
var wid string
if err := json.Unmarshal(data, &wid); err != nil {
logx.Error(" invalid format of wid :", wid)
r.w.incomeDataFormatErrResponse("invalid format of wid")
return
}
//解密
decryptionWid, err := encryption_decryption.CBCDecrypt(wid)
if err != nil {
r.w.reuseLastConnErrResponse("invalid wid")
return
}
lendecryptionWid := len(decryptionWid)
//合成client后缀,不是同个后缀的不能复用
userPart := getUserJoinPart(r.w.userId, r.w.guestId, r.w.userAgent)
lenUserPart := len(userPart)
if lendecryptionWid <= lenUserPart {
r.w.reuseLastConnErrResponse("length of client id is to short")
return
}
//尾部不同不能复用
if decryptionWid[lendecryptionWid-lenUserPart:] != userPart {
r.w.reuseLastConnErrResponse("the client id is not belong to you before")
return
}
//存在是不能给他申请重新绑定
if v, ok := mapConnPool.Load(wid); ok {
obj, ok := v.(wsConnectItem)
if !ok {
logx.Error("连接断言失败")
}
//是当前自己占用(无需处理)
if obj.uniqueId == r.w.uniqueId {
rsp := r.w.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, wid)
r.w.sendToOutChan(rsp)
return
} else {
r.w.reuseLastConnErrResponse("the wid is used by other people")
return
}
}
//重新绑定
r.w.uniqueId = wid
mapConnPool.Store(wid, *r.w)
rsp := r.w.respondDataFormat(constants.WEBSOCKET_CONNECT_SUCCESS, wid)
r.w.sendToOutChan(rsp)
return
}
// 获取用户拼接部分(复用标识用到)
func getUserJoinPart(userId, guestId int64, userAgent string) string {
return fmt.Sprintf("|_%d_%d_|_%s_|", userId, guestId, userAgent)
}