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