package main import ( "github.com/gorilla/websocket" "sync" ) type wsQ struct { wsMutex sync.Mutex Clients map[*websocket.Conn]string ClientsBySession map[string]*websocket.Conn } var wsq = wsQ{ Clients: make(map[*websocket.Conn]string), ClientsBySession: make(map[string]*websocket.Conn), } func (m *wsQ) addConnection(c *websocket.Conn) { m.wsMutex.Lock() m.Clients[c] = "" m.wsMutex.Unlock() } func (m *wsQ) MapSessionToConnection(sid string, c *websocket.Conn) { m.wsMutex.Lock() m.ClientsBySession[sid] = c m.Clients[c] = sid m.wsMutex.Unlock() } func (m *wsQ) has(conn *websocket.Conn) (yes bool) { m.wsMutex.Lock() _, ok := m.Clients[conn] m.wsMutex.Unlock() return ok } func (m *wsQ) getConnBySessionId(sid string) (conn *websocket.Conn) { conn = nil m.wsMutex.Lock() for k, v := range m.ClientsBySession { if k == sid { conn = v break } } m.wsMutex.Unlock() return } func (m *wsQ) del(conn *websocket.Conn) { m.wsMutex.Lock() if sid, exist := m.Clients[conn]; exist { delete(m.Clients, conn) delete(m.ClientsBySession, sid) } m.wsMutex.Unlock() } func (m *wsQ) delBySessionId(sid string) { m.wsMutex.Lock() if conn, exist := m.ClientsBySession[sid]; exist { delete(m.ClientsBySession, sid) delete(m.Clients, conn) } m.wsMutex.Unlock() } func (m *wsQ) wsDoBroadcast(msg string, except string) { toBeRemoved := make([]*websocket.Conn, 0, 20) m.wsMutex.Lock() for k, _ := range m.Clients { if m.ClientsBySession[except] == k { continue } err := k.WriteMessage(websocket.TextMessage, []byte(msg)) if err != nil { toBeRemoved = append(toBeRemoved, k) } } // remove all those have errors for communication for _, v := range toBeRemoved { delete(m.Clients, v) } m.wsMutex.Unlock() }