feat: tipos WSHub, WSClient, WSMessage, SSEEvent (issue 0011 fase 1)
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package infra
|
||||
|
||||
// WSHub gestiona el ciclo de vida de conexiones WebSocket.
|
||||
// Mantiene un mapa de clientes activos y canales para registro,
|
||||
// desregistro y broadcast. Se ejecuta como goroutine via su Run().
|
||||
type WSHub struct {
|
||||
Clients map[*WSClient]bool
|
||||
Broadcast chan []byte
|
||||
Register chan *WSClient
|
||||
Unregister chan *WSClient
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
// NewWSHub crea un WSHub vacio con canales inicializados.
|
||||
// Ejecutar Run() en una goroutine para activar el loop de eventos.
|
||||
func NewWSHub() *WSHub {
|
||||
return &WSHub{
|
||||
Clients: make(map[*WSClient]bool),
|
||||
Broadcast: make(chan []byte, 256),
|
||||
Register: make(chan *WSClient),
|
||||
Unregister: make(chan *WSClient),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Run ejecuta el loop principal del hub. Atiende registros, desregistros
|
||||
// y broadcasts en un select. Bloqueante: lanzar como goroutine.
|
||||
// Para parar, llamar a Stop().
|
||||
func (h *WSHub) Run() {
|
||||
for {
|
||||
select {
|
||||
case <-h.done:
|
||||
// Cerrar todos los Send y vaciar el mapa
|
||||
for client := range h.Clients {
|
||||
delete(h.Clients, client)
|
||||
close(client.Send)
|
||||
}
|
||||
return
|
||||
case client := <-h.Register:
|
||||
h.Clients[client] = true
|
||||
case client := <-h.Unregister:
|
||||
if _, ok := h.Clients[client]; ok {
|
||||
delete(h.Clients, client)
|
||||
close(client.Send)
|
||||
}
|
||||
case msg := <-h.Broadcast:
|
||||
for client := range h.Clients {
|
||||
select {
|
||||
case client.Send <- msg:
|
||||
default:
|
||||
// Cliente lento: desconectar
|
||||
delete(h.Clients, client)
|
||||
close(client.Send)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stop cierra el loop de Run() y limpia todos los clientes.
|
||||
// Idempotente — llamar mas de una vez no panica.
|
||||
func (h *WSHub) Stop() {
|
||||
select {
|
||||
case <-h.done:
|
||||
// Ya cerrado
|
||||
default:
|
||||
close(h.done)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user