mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-05-06 01:55:58 +08:00
ws support same terminal login
This commit is contained in:
@@ -45,15 +45,13 @@ type WServer struct {
|
||||
wsAddr string
|
||||
wsMaxConnNum int
|
||||
wsUpGrader *websocket.Upgrader
|
||||
wsConnToUser map[*UserConn]map[int]string
|
||||
wsUserToConn map[string]map[int]*UserConn
|
||||
wsUserToConn map[string]map[int][]*UserConn
|
||||
}
|
||||
|
||||
func (ws *WServer) onInit(wsPort int) {
|
||||
ws.wsAddr = ":" + utils.IntToString(wsPort)
|
||||
ws.wsMaxConnNum = config.Config.LongConnSvr.WebsocketMaxConnNum
|
||||
ws.wsConnToUser = make(map[*UserConn]map[int]string)
|
||||
ws.wsUserToConn = make(map[string]map[int]*UserConn)
|
||||
ws.wsUserToConn = make(map[string]map[int][]*UserConn)
|
||||
ws.wsUpGrader = &websocket.Upgrader{
|
||||
HandshakeTimeout: time.Duration(config.Config.LongConnSvr.WebsocketTimeOut) * time.Second,
|
||||
ReadBufferSize: config.Config.LongConnSvr.WebsocketMaxMsgLen,
|
||||
@@ -203,8 +201,11 @@ func (ws *WServer) MultiTerminalLoginCheckerWithLock(uid string, platformID int,
|
||||
fallthrough
|
||||
case constant.AllLoginButSameTermKick:
|
||||
if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // user->map[platform->conn]
|
||||
if oldConn, ok := oldConnMap[platformID]; ok {
|
||||
if oldConns, ok := oldConnMap[platformID]; ok {
|
||||
log.NewDebug(operationID, uid, platformID, "kick old conn")
|
||||
for _, conn := range oldConns {
|
||||
ws.sendKickMsg(conn, operationID)
|
||||
}
|
||||
m, err := db.DB.GetTokenMapByUidPid(uid, constant.PlatformIDToName(platformID))
|
||||
if err != nil && err != go_redis.Nil {
|
||||
log.NewError(operationID, "get token from redis err", err.Error(), uid, constant.PlatformIDToName(platformID))
|
||||
@@ -227,16 +228,12 @@ func (ws *WServer) MultiTerminalLoginCheckerWithLock(uid string, platformID int,
|
||||
log.NewError(operationID, "SetTokenMapByUidPid err", err.Error(), uid, platformID, m)
|
||||
return
|
||||
}
|
||||
err = oldConn.Close()
|
||||
//delete(oldConnMap, platformID)
|
||||
|
||||
delete(oldConnMap, platformID)
|
||||
ws.wsUserToConn[uid] = oldConnMap
|
||||
if len(oldConnMap) == 0 {
|
||||
delete(ws.wsUserToConn, uid)
|
||||
}
|
||||
delete(ws.wsConnToUser, oldConn)
|
||||
if err != nil {
|
||||
log.NewError(operationID, "conn close err", err.Error(), uid, platformID)
|
||||
}
|
||||
} else {
|
||||
log.NewWarn(operationID, "abnormal uid-conn ", uid, platformID, oldConnMap[platformID])
|
||||
}
|
||||
@@ -259,9 +256,11 @@ func (ws *WServer) MultiTerminalLoginChecker(uid string, platformID int, newConn
|
||||
fallthrough
|
||||
case constant.AllLoginButSameTermKick:
|
||||
if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // user->map[platform->conn]
|
||||
if oldConn, ok := oldConnMap[platformID]; ok {
|
||||
if oldConns, ok := oldConnMap[platformID]; ok {
|
||||
log.NewDebug(operationID, uid, platformID, "kick old conn")
|
||||
ws.sendKickMsg(oldConn, operationID)
|
||||
for _, conn := range oldConns {
|
||||
ws.sendKickMsg(conn, operationID)
|
||||
}
|
||||
m, err := db.DB.GetTokenMapByUidPid(uid, constant.PlatformIDToName(platformID))
|
||||
if err != nil && err != go_redis.Nil {
|
||||
log.NewError(operationID, "get token from redis err", err.Error(), uid, constant.PlatformIDToName(platformID))
|
||||
@@ -284,16 +283,11 @@ func (ws *WServer) MultiTerminalLoginChecker(uid string, platformID int, newConn
|
||||
log.NewError(operationID, "SetTokenMapByUidPid err", err.Error(), uid, platformID, m)
|
||||
return
|
||||
}
|
||||
err = oldConn.Close()
|
||||
delete(oldConnMap, platformID)
|
||||
ws.wsUserToConn[uid] = oldConnMap
|
||||
if len(oldConnMap) == 0 {
|
||||
delete(ws.wsUserToConn, uid)
|
||||
}
|
||||
delete(ws.wsConnToUser, oldConn)
|
||||
if err != nil {
|
||||
log.NewError(operationID, "conn close err", err.Error(), uid, platformID)
|
||||
}
|
||||
callbackResp := callbackUserKickOff(operationID, uid, platformID)
|
||||
if callbackResp.ErrCode != 0 {
|
||||
log.NewError(operationID, utils.GetSelfFuncName(), "callbackUserOffline failed", callbackResp)
|
||||
@@ -328,6 +322,11 @@ func (ws *WServer) sendKickMsg(oldConn *UserConn, operationID string) {
|
||||
if err != nil {
|
||||
log.NewError(mReply.OperationID, mReply.ReqIdentifier, mReply.ErrCode, mReply.ErrMsg, "sendKickMsg WS WriteMsg error", oldConn.RemoteAddr().String(), err.Error())
|
||||
}
|
||||
errClose := oldConn.Close()
|
||||
if errClose != nil {
|
||||
log.NewError(mReply.OperationID, mReply.ReqIdentifier, mReply.ErrCode, mReply.ErrMsg, "close old conn error", oldConn.RemoteAddr().String(), err.Error())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WServer) addUserConn(uid string, platformID int, conn *UserConn, token string, connID, operationID string) {
|
||||
@@ -341,23 +340,24 @@ func (ws *WServer) addUserConn(uid string, platformID int, conn *UserConn, token
|
||||
go ws.MultiTerminalLoginRemoteChecker(uid, int32(platformID), token, operationID)
|
||||
ws.MultiTerminalLoginChecker(uid, platformID, conn, token, operationID)
|
||||
if oldConnMap, ok := ws.wsUserToConn[uid]; ok {
|
||||
oldConnMap[platformID] = conn
|
||||
if conns, ok := oldConnMap[platformID]; ok {
|
||||
conns = append(conns, conn)
|
||||
oldConnMap[platformID] = conns
|
||||
} else {
|
||||
conns := make([]*UserConn, 2)
|
||||
conns = append(conns, conn)
|
||||
oldConnMap[platformID] = conns
|
||||
}
|
||||
ws.wsUserToConn[uid] = oldConnMap
|
||||
log.Debug(operationID, "user not first come in, add conn ", uid, platformID, conn, oldConnMap)
|
||||
} else {
|
||||
i := make(map[int]*UserConn)
|
||||
i[platformID] = conn
|
||||
i := make(map[int][]*UserConn)
|
||||
conns := make([]*UserConn, 2)
|
||||
conns = append(conns, conn)
|
||||
i[platformID] = conns
|
||||
ws.wsUserToConn[uid] = i
|
||||
log.Debug(operationID, "user first come in, new user, conn", uid, platformID, conn, ws.wsUserToConn[uid])
|
||||
}
|
||||
if oldStringMap, ok := ws.wsConnToUser[conn]; ok {
|
||||
oldStringMap[platformID] = uid
|
||||
ws.wsConnToUser[conn] = oldStringMap
|
||||
} else {
|
||||
i := make(map[int]string)
|
||||
i[platformID] = uid
|
||||
ws.wsConnToUser[conn] = i
|
||||
}
|
||||
count := 0
|
||||
for _, v := range ws.wsUserToConn {
|
||||
count = count + len(v)
|
||||
@@ -370,36 +370,39 @@ func (ws *WServer) delUserConn(conn *UserConn) {
|
||||
rwLock.Lock()
|
||||
defer rwLock.Unlock()
|
||||
operationID := utils.OperationIDGenerator()
|
||||
var uid string
|
||||
var platform int
|
||||
if oldStringMap, okg := ws.wsConnToUser[conn]; okg {
|
||||
for k, v := range oldStringMap {
|
||||
platform = k
|
||||
uid = v
|
||||
}
|
||||
if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // only recycle self conn
|
||||
if oldconn, okMap := oldConnMap[platform]; okMap {
|
||||
if oldconn == conn {
|
||||
delete(oldConnMap, platform)
|
||||
platform := int(conn.PlatformID)
|
||||
|
||||
if oldConnMap, ok := ws.wsUserToConn[conn.userID]; ok { // only recycle self conn
|
||||
if oldconns, okMap := oldConnMap[platform]; okMap {
|
||||
var flag bool
|
||||
a := make([]*UserConn, 2)
|
||||
for _, client := range oldconns {
|
||||
if client != conn {
|
||||
a = append(a, client)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
ws.wsUserToConn[uid] = oldConnMap
|
||||
if len(oldConnMap) == 0 {
|
||||
delete(ws.wsUserToConn, uid)
|
||||
if flag {
|
||||
oldConnMap[platform] = a
|
||||
} else {
|
||||
delete(oldConnMap, platform)
|
||||
}
|
||||
count := 0
|
||||
for _, v := range ws.wsUserToConn {
|
||||
count = count + len(v)
|
||||
}
|
||||
log.Debug(operationID, "WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "disconnection_uid", uid, "disconnection_platform", platform, "online_user_num", len(ws.wsUserToConn), "online_conn_num", count)
|
||||
} else {
|
||||
log.Debug(operationID, "WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "disconnection_uid", uid, "disconnection_platform", platform, "online_user_num", len(ws.wsUserToConn))
|
||||
|
||||
}
|
||||
delete(ws.wsConnToUser, conn)
|
||||
ws.wsUserToConn[conn.userID] = oldConnMap
|
||||
if len(oldConnMap) == 0 {
|
||||
delete(ws.wsUserToConn, conn.userID)
|
||||
}
|
||||
count := 0
|
||||
for _, v := range ws.wsUserToConn {
|
||||
count = count + len(v)
|
||||
}
|
||||
log.Debug(operationID, "WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "disconnection_uid", conn.userID, "disconnection_platform", platform, "online_user_num", len(ws.wsUserToConn), "online_conn_num", count)
|
||||
}
|
||||
|
||||
err := conn.Close()
|
||||
if err != nil {
|
||||
log.Error(operationID, " close err", "", "uid", uid, "platform", platform)
|
||||
log.Error(operationID, " close err", "", "uid", conn.userID, "platform", platform)
|
||||
}
|
||||
if conn.PlatformID == 0 || conn.connID == "" {
|
||||
log.NewWarn(operationID, utils.GetSelfFuncName(), "PlatformID or connID is null", conn.PlatformID, conn.connID)
|
||||
@@ -412,21 +415,21 @@ func (ws *WServer) delUserConn(conn *UserConn) {
|
||||
|
||||
}
|
||||
|
||||
func (ws *WServer) getUserConn(uid string, platform int) *UserConn {
|
||||
// func (ws *WServer) getUserConn(uid string, platform int) *UserConn {
|
||||
// rwLock.RLock()
|
||||
// defer rwLock.RUnlock()
|
||||
// if connMap, ok := ws.wsUserToConn[uid]; ok {
|
||||
// if conn, flag := connMap[platform]; flag {
|
||||
// return conn
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
func (ws *WServer) getUserAllCons(uid string) map[int][]*UserConn {
|
||||
rwLock.RLock()
|
||||
defer rwLock.RUnlock()
|
||||
if connMap, ok := ws.wsUserToConn[uid]; ok {
|
||||
if conn, flag := connMap[platform]; flag {
|
||||
return conn
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (ws *WServer) getUserAllCons(uid string) map[int]*UserConn {
|
||||
rwLock.RLock()
|
||||
defer rwLock.RUnlock()
|
||||
if connMap, ok := ws.wsUserToConn[uid]; ok {
|
||||
newConnMap := make(map[int]*UserConn)
|
||||
newConnMap := make(map[int][]*UserConn)
|
||||
for k, v := range connMap {
|
||||
newConnMap[k] = v
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user