48 lines
1.2 KiB
Go
48 lines
1.2 KiB
Go
package main
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
// ConnectionManager fans out messages to WebSocket connections per
|
|
// conversation. In-memory, single-process -- fine for a small closed beta
|
|
// (roadmap.md Phase 1); revisit if the relay needs to scale past one process.
|
|
type ConnectionManager struct {
|
|
mu sync.Mutex
|
|
conns map[uint][]*websocket.Conn
|
|
}
|
|
|
|
func newConnectionManager() *ConnectionManager {
|
|
return &ConnectionManager{conns: make(map[uint][]*websocket.Conn)}
|
|
}
|
|
|
|
func (m *ConnectionManager) add(conversationID uint, conn *websocket.Conn) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
m.conns[conversationID] = append(m.conns[conversationID], conn)
|
|
}
|
|
|
|
func (m *ConnectionManager) remove(conversationID uint, conn *websocket.Conn) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
peers := m.conns[conversationID]
|
|
for i, c := range peers {
|
|
if c == conn {
|
|
m.conns[conversationID] = append(peers[:i], peers[i+1:]...)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *ConnectionManager) broadcast(conversationID uint, payload interface{}) {
|
|
m.mu.Lock()
|
|
peers := append([]*websocket.Conn(nil), m.conns[conversationID]...)
|
|
m.mu.Unlock()
|
|
|
|
for _, c := range peers {
|
|
_ = c.WriteJSON(payload)
|
|
}
|
|
}
|