50 lines
2.5 KiB
Markdown
50 lines
2.5 KiB
Markdown
---
|
|
name: ws_handler
|
|
kind: function
|
|
lang: go
|
|
domain: infra
|
|
version: "1.0.0"
|
|
purity: impure
|
|
signature: "func WSHandler(hub *WSHub, origins []string) http.HandlerFunc"
|
|
description: "Retorna un http.HandlerFunc que upgradea la conexion HTTP a WebSocket via WSUpgrader, crea un WSClient con ID hex aleatorio, lo registra en el hub y lanza readPump y writePump como goroutines. La readPump bloquea el handler para mantener la request viva. Al desconectar (error de I/O o canal cerrado) se desregistra el cliente y se cierra la conexion limpiamente."
|
|
tags: [websocket, handler, http, server, hub, infra, realtime]
|
|
uses_functions: [ws_upgrader_go_infra]
|
|
uses_types: [WSHub_go_infra, WSClient_go_infra]
|
|
returns: []
|
|
returns_optional: false
|
|
error_type: "error_go_core"
|
|
imports: [context, crypto/rand, encoding/hex, net/http, time, "nhooyr.io/websocket"]
|
|
params:
|
|
- name: hub
|
|
desc: "*WSHub donde se registran los clientes que se conecten via este handler. Debe estar corriendo (hub.Run() lanzado en goroutine)."
|
|
- name: origins
|
|
desc: "lista de patrones de origen permitidos para el upgrade. Pasa directamente a WSUpgrader. Para dev: `[\"*\"]`. Para prod: lista explicita."
|
|
output: "http.HandlerFunc lista para montarse en una ruta GET. Cada conexion entrante crea un cliente nuevo en el hub."
|
|
tested: true
|
|
tests: ["upgradea conexion y registra cliente en hub", "broadcast del hub llega al cliente conectado", "desregistra cliente al desconectar", "multiples clientes reciben el broadcast"]
|
|
test_file_path: "functions/infra/ws_test.go"
|
|
file_path: "functions/infra/ws_handler.go"
|
|
---
|
|
|
|
## Ejemplo
|
|
|
|
```go
|
|
hub := NewWSHub()
|
|
go hub.Run()
|
|
defer hub.Stop()
|
|
|
|
routes := []Route{
|
|
{Method: "GET", Path: "/ws", Handler: WSHandler(hub, []string{"example.com"})},
|
|
}
|
|
mux := HTTPRouter(routes)
|
|
HTTPServe(":8080", mux, ctx)
|
|
```
|
|
|
|
## Notas
|
|
|
|
El handler asigna un ID hex aleatorio de 16 caracteres a cada cliente (`crypto/rand`). Si se quiere usar IDs propios (UUID, username autenticado), envolver el handler para sobreescribir `client.ID` antes del Register.
|
|
|
|
readPump publica todos los mensajes recibidos al `hub.Broadcast` — modo chat-like por defecto. Para procesar mensajes con un callback (sin reenviar a todos), copiar el codigo y reemplazar el Broadcast por la logica deseada. Esta separacion es deliberada: el hub es un mecanismo de fan-out, no un router de mensajes.
|
|
|
|
writePump usa write deadline de 10s — si un Write tarda mas, asume cliente muerto y termina. Esto previene goroutines colgadas si el cliente cierra TCP sin enviar Close frame.
|