83 lines
1.7 KiB
Go
Raw Normal View History

package websocket
import "sync"
type Hub struct {
clients map[string]map[*Client]bool // companyID -> clients
broadcast chan *Event
register chan *Client
unregister chan *Client
mu sync.RWMutex
}
func NewHub() *Hub {
return &Hub{
clients: make(map[string]map[*Client]bool),
broadcast: make(chan *Event, 256),
register: make(chan *Client),
unregister: make(chan *Client),
}
}
func (h *Hub) Run() {
for {
select {
case client := <-h.register:
h.mu.Lock()
if h.clients[client.companyID] == nil {
h.clients[client.companyID] = make(map[*Client]bool)
}
h.clients[client.companyID][client] = true
h.mu.Unlock()
case client := <-h.unregister:
h.mu.Lock()
if clients, ok := h.clients[client.companyID]; ok {
if _, exists := clients[client]; exists {
delete(clients, client)
close(client.send)
if len(clients) == 0 {
delete(h.clients, client.companyID)
}
}
}
h.mu.Unlock()
case event := <-h.broadcast:
h.mu.RLock()
if event.CompanyID != "" {
h.broadcastToCompanyLocked(event.CompanyID, event)
} else {
for companyID := range h.clients {
h.broadcastToCompanyLocked(companyID, event)
}
}
h.mu.RUnlock()
}
}
}
func (h *Hub) broadcastToCompanyLocked(companyID string, event *Event) {
data, err := event.Marshal()
if err != nil {
return
}
for client := range h.clients[companyID] {
select {
case client.send <- data:
default:
close(client.send)
delete(h.clients[companyID], client)
}
}
}
func (h *Hub) Broadcast(event *Event) {
h.broadcast <- event
}
func (h *Hub) BroadcastToCompany(companyID string, event *Event) {
event.CompanyID = companyID
h.broadcast <- event
}