Files
social/core/connection.go

118 lines
2.7 KiB
Go

package core
import (
"encoding/json"
"sync"
"github.com/gorilla/websocket"
"go.mongodb.org/mongo-driver/bson/primitive"
"repositories.action2quare.com/ayo/gocommon"
"repositories.action2quare.com/ayo/gocommon/logger"
"repositories.action2quare.com/ayo/gocommon/wshandler"
)
type connWithFriends struct {
c *websocket.Conn
friends []*friendDoc
initialized bool
}
type connections struct {
connLock sync.Mutex
conns map[primitive.ObjectID]*connWithFriends
redison *gocommon.RedisonHandler
}
func (cs *connections) new(accid primitive.ObjectID, conn *websocket.Conn) {
cs.connLock.Lock()
defer cs.connLock.Unlock()
cs.conns[accid] = &connWithFriends{
c: conn,
initialized: false,
}
}
func (cs *connections) delete(accid primitive.ObjectID) {
cs.connLock.Lock()
defer cs.connLock.Unlock()
delete(cs.conns, accid)
}
func (cs *connections) conn(accid primitive.ObjectID) *websocket.Conn {
cs.connLock.Lock()
defer cs.connLock.Unlock()
if cf, ok := cs.conns[accid]; ok {
return cf.c
}
return nil
}
func (cs *connections) addFriend(accid primitive.ObjectID, fdoc *friendDoc) bool {
cs.connLock.Lock()
defer cs.connLock.Unlock()
if cf, ok := cs.conns[accid]; ok {
if cf.initialized {
cf.friends = append(cf.friends, fdoc)
return true
}
}
return false
}
func (cs *connections) initFriends(accid primitive.ObjectID, fdocs []*friendDoc) {
cs.connLock.Lock()
defer cs.connLock.Unlock()
if cf, ok := cs.conns[accid]; ok {
cf.friends = fdocs
cf.initialized = true
}
}
func (cs *connections) clearFriends(accid primitive.ObjectID) (out []*friendDoc) {
cs.connLock.Lock()
defer cs.connLock.Unlock()
if cf, ok := cs.conns[accid]; ok {
out = cf.friends
cf.friends = nil
cf.initialized = false
}
return
}
func (cs *connections) writeMessage(acc primitive.ObjectID, src any) {
cs.connLock.Lock()
defer cs.connLock.Unlock()
conn := cs.conns[acc]
if conn == nil {
return
}
if bt, err := json.Marshal(src); err == nil {
pmsg, err := websocket.NewPreparedMessage(websocket.TextMessage, bt)
if err != nil {
logger.Println("connections.writeMessage failed :", err)
} else {
conn.c.WritePreparedMessage(pmsg)
}
}
}
func (cs *connections) ClientConnected(conn *websocket.Conn, callby *wshandler.Sender) {
cs.new(callby.Accid, conn)
cs.redison.JSONSet(callby.Accid.Hex(), "$", map[string]any{}, gocommon.RedisonSetOptionNX)
}
func (cs *connections) ClientDisconnected(msg string, callby *wshandler.Sender) {
cs.redison.JSONDel(callby.Accid.Hex(), "$")
cs.delete(callby.Accid)
}
func makeConnections(redison *gocommon.RedisonHandler) *connections {
return &connections{
conns: make(map[primitive.ObjectID]*connWithFriends),
redison: redison,
}
}