package server import ( uch "git.loafle.net/commons_go/util/channel" ogw "git.loafle.net/overflow/overflow_gateway_websocket" ) type socketsChannelAction struct { uch.Action path string uid string soc ogw.Socket } type sockets struct { s map[string]ogw.Socket sr map[ogw.Socket]string } func (s *sockets) addSocket(uid string, soc ogw.Socket) { s.s[uid] = soc s.sr[soc] = uid } func (s *sockets) removeSocket(soc ogw.Socket) { var uid string var ok bool if uid, ok = s.sr[soc]; !ok { return } delete(s.s, uid) delete(s.sr, soc) } func (s *sockets) getSocket(uid string) ogw.Socket { return s.s[uid] } func (s *sockets) getUID(soc ogw.Socket) string { return s.sr[soc] } type SocketManager interface { AddSocket(path string, uid string, soc ogw.Socket) RemoveSocket(path string, soc ogw.Socket) GetSocket(path string, uid string) ogw.Socket GetUID(path string, soc ogw.Socket) string } type socketManager struct { sMap map[string]*sockets sCh chan socketsChannelAction } var _m SocketManager func init() { _m = New() } func New() SocketManager { m := &socketManager{ sMap: make(map[string]*sockets), sCh: make(chan socketsChannelAction), } go m.listenChannel() return m } func AddSocket(path string, uid string, soc ogw.Socket) { _m.AddSocket(path, uid, soc) } func (m *socketManager) AddSocket(path string, uid string, soc ogw.Socket) { ca := socketsChannelAction{ path: path, uid: uid, soc: soc, } ca.Type = uch.ActionTypeCreate m.sCh <- ca } func RemoveSocket(path string, soc ogw.Socket) { _m.RemoveSocket(path, soc) } func (m *socketManager) RemoveSocket(path string, soc ogw.Socket) { ca := socketsChannelAction{ path: path, soc: soc, } ca.Type = uch.ActionTypeDelete m.sCh <- ca } func GetSocket(path string, uid string) ogw.Socket { return _m.GetSocket(path, uid) } func (m *socketManager) GetSocket(path string, uid string) ogw.Socket { var s *sockets var ok bool if s, ok = m.sMap[path]; !ok { return nil } return s.getSocket(uid) } func GetUID(path string, soc ogw.Socket) string { return _m.GetUID(path, soc) } func (m *socketManager) GetUID(path string, soc ogw.Socket) string { var s *sockets var ok bool if s, ok = m.sMap[path]; !ok { return "" } return s.getUID(soc) } func (m *socketManager) listenChannel() { for { select { case ca := <-m.sCh: switch ca.Type { case uch.ActionTypeCreate: var s *sockets var ok bool if s, ok = m.sMap[ca.path]; !ok { s = &sockets{ s: make(map[string]ogw.Socket), sr: make(map[ogw.Socket]string), } m.sMap[ca.path] = s } s.addSocket(ca.uid, ca.soc) break case uch.ActionTypeDelete: var s *sockets var ok bool if s, ok = m.sMap[ca.path]; !ok { return } s.removeSocket(ca.soc) break } } } }