use sync.map

pull/58/head
shingle 4 years ago
parent 7f2270844e
commit f600b888f3

@ -4,25 +4,27 @@ import (
"Open_IM/src/common/config" "Open_IM/src/common/config"
"Open_IM/src/common/log" "Open_IM/src/common/log"
"Open_IM/src/utils" "Open_IM/src/utils"
"github.com/gorilla/websocket"
"net/http" "net/http"
"sync"
"time" "time"
"github.com/gorilla/websocket"
) )
type WServer struct { type WServer struct {
wsAddr string wsAddr string
wsMaxConnNum int wsMaxConnNum int
wsUpGrader *websocket.Upgrader wsUpGrader *websocket.Upgrader
wsConnToUser map[*websocket.Conn]string wsConnToUser sync.Map
wsUserToConn map[string]*websocket.Conn wsUserToConn sync.Map
} }
func (ws *WServer) onInit(wsPort int) { func (ws *WServer) onInit(wsPort int) {
ip := utils.ServerIP ip := utils.ServerIP
ws.wsAddr = ip + ":" + utils.IntToString(wsPort) ws.wsAddr = ip + ":" + utils.IntToString(wsPort)
ws.wsMaxConnNum = config.Config.LongConnSvr.WebsocketMaxConnNum ws.wsMaxConnNum = config.Config.LongConnSvr.WebsocketMaxConnNum
ws.wsConnToUser = make(map[*websocket.Conn]string) ws.wsConnToUser = sync.Map{}
ws.wsUserToConn = make(map[string]*websocket.Conn) ws.wsUserToConn = sync.Map{}
ws.wsUpGrader = &websocket.Upgrader{ ws.wsUpGrader = &websocket.Upgrader{
HandshakeTimeout: time.Duration(config.Config.LongConnSvr.WebsocketTimeOut) * time.Second, HandshakeTimeout: time.Duration(config.Config.LongConnSvr.WebsocketTimeOut) * time.Second,
ReadBufferSize: config.Config.LongConnSvr.WebsocketMaxMsgLen, ReadBufferSize: config.Config.LongConnSvr.WebsocketMaxMsgLen,
@ -80,18 +82,20 @@ func (ws *WServer) writeMsg(conn *websocket.Conn, a int, msg []byte) error {
func (ws *WServer) addUserConn(uid string, conn *websocket.Conn) { func (ws *WServer) addUserConn(uid string, conn *websocket.Conn) {
rwLock.Lock() rwLock.Lock()
defer rwLock.Unlock() defer rwLock.Unlock()
if oldConn, ok := ws.wsUserToConn[uid]; ok { if v, ok := ws.wsUserToConn.Load(uid); ok {
oldConn := v.(*websocket.Conn)
err := oldConn.Close() err := oldConn.Close()
delete(ws.wsConnToUser, oldConn) ws.wsConnToUser.Delete(oldConn)
if err != nil { if err != nil {
log.ErrorByKv("close err", "", "uid", uid, "conn", conn) log.ErrorByKv("close err", "", "uid", uid, "conn", conn)
} }
} else { } else {
log.InfoByKv("this user is first login", "", "uid", uid) log.InfoByKv("this user is first login", "", "uid", uid)
} }
ws.wsConnToUser[conn] = uid
ws.wsUserToConn[uid] = conn ws.wsConnToUser.Store(conn, uid)
log.WarnByKv("WS Add operation", "", "wsUser added", ws.wsUserToConn, "uid", uid, "online_num", len(ws.wsUserToConn)) ws.wsUserToConn.Store(uid, conn)
log.WarnByKv("WS Add operation", "", "wsUser added", ws.wsUserToConn, "uid", uid, "online_num", ws.onlineNum())
} }
@ -99,15 +103,16 @@ func (ws *WServer) delUserConn(conn *websocket.Conn) {
rwLock.Lock() rwLock.Lock()
defer rwLock.Unlock() defer rwLock.Unlock()
var uidPlatform string var uidPlatform string
if uid, ok := ws.wsConnToUser[conn]; ok { if v, ok := ws.wsConnToUser.Load(conn); ok {
uid := v.(string)
uidPlatform = uid uidPlatform = uid
if _, ok = ws.wsUserToConn[uid]; ok { if _, ok := ws.wsUserToConn.Load(uid); ok {
delete(ws.wsUserToConn, uid) ws.wsUserToConn.Delete(uid)
log.WarnByKv("WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "uid", uid, "online_num", len(ws.wsUserToConn)) log.WarnByKv("WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "uid", uid, "online_num", ws.onlineNum())
} else { } else {
log.WarnByKv("uid not exist", "", "wsUser deleted", ws.wsUserToConn, "uid", uid, "online_num", len(ws.wsUserToConn)) log.WarnByKv("uid not exist", "", "wsUser deleted", ws.wsUserToConn, "uid", uid, "online_num", ws.onlineNum())
} }
delete(ws.wsConnToUser, conn) ws.wsConnToUser.Delete(conn)
} }
err := conn.Close() err := conn.Close()
if err != nil { if err != nil {
@ -119,7 +124,8 @@ func (ws *WServer) delUserConn(conn *websocket.Conn) {
func (ws *WServer) getUserConn(uid string) *websocket.Conn { func (ws *WServer) getUserConn(uid string) *websocket.Conn {
rwLock.RLock() rwLock.RLock()
defer rwLock.RUnlock() defer rwLock.RUnlock()
if conn, ok := ws.wsUserToConn[uid]; ok { if v, ok := ws.wsUserToConn.Load(uid); ok {
conn := v.(*websocket.Conn)
return conn return conn
} }
return nil return nil
@ -127,8 +133,8 @@ func (ws *WServer) getUserConn(uid string) *websocket.Conn {
func (ws *WServer) getUserUid(conn *websocket.Conn) string { func (ws *WServer) getUserUid(conn *websocket.Conn) string {
rwLock.RLock() rwLock.RLock()
defer rwLock.RUnlock() defer rwLock.RUnlock()
if v, ok := ws.wsConnToUser.Load(conn); ok {
if uid, ok := ws.wsConnToUser[conn]; ok { uid := v.(string)
return uid return uid
} }
return "" return ""
@ -154,3 +160,12 @@ func (ws *WServer) headerCheck(w http.ResponseWriter, r *http.Request) bool {
} }
} }
func (ws *WServer) onlineNum() int {
var count int
ws.wsUserToConn.Range(func(key, value interface{}) bool {
count++
return true
})
return count
}

Loading…
Cancel
Save