package dashboard
import (
"context"
"sync"
"github.com/gorilla/websocket"
)
type Hub struct {
clients map[*websocket.Conn]bool
broadcast chan []byte
register chan *websocket.Conn
unregister chan *websocket.Conn
mu sync.Mutex
ctx context.Context
cancel context.CancelFunc
}
func NewHub(ctx context.Context) *Hub {
hctx, cancel := context.WithCancel(ctx)
return &Hub{
clients: make(map[*websocket.Conn]bool),
broadcast: make(chan []byte, 256),
register: make(chan *websocket.Conn),
unregister: make(chan *websocket.Conn),
ctx: hctx,
cancel: cancel,
}
}
func (h *Hub) Run() {
for {
select {
case <-h.ctx.Done():
h.mu.Lock()
for c := range h.clients {
_ = c.Close()
}
h.mu.Unlock()
return
case c := <-h.register:
h.mu.Lock()
h.clients[c] = true
h.mu.Unlock()
case c := <-h.unregister:
h.mu.Lock()
delete(h.clients, c)
_ = c.Close()
h.mu.Unlock()
case msg := <-h.broadcast:
h.mu.Lock()
for c := range h.clients {
_ = c.WriteMessage(websocket.TextMessage, msg)
}
h.mu.Unlock()
}
}
}
func (h *Hub) Shutdown() {
h.cancel()
}