feat: SSE handler, send y keepalive (issue 0011 fase 2)

This commit is contained in:
2026-04-18 17:25:03 +02:00
parent 0255207514
commit 637bc8fd34
7 changed files with 546 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
package infra
import "net/http"
// SSEHandler retorna un http.HandlerFunc que setea los headers SSE,
// consume eventos del canal y los envia con flush. Cierra limpiamente
// si el cliente se desconecta (context cancelado) o si el canal se cierra.
//
// Headers seteados:
// Content-Type: text/event-stream
// Cache-Control: no-cache
// Connection: keep-alive
// X-Accel-Buffering: no (deshabilita buffering en nginx)
func SSEHandler(events <-chan SSEEvent) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "streaming unsupported", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("X-Accel-Buffering", "no")
w.WriteHeader(http.StatusOK)
flusher.Flush()
ctx := r.Context()
for {
select {
case <-ctx.Done():
return
case ev, ok := <-events:
if !ok {
return
}
if err := SSESend(w, ev); err != nil {
return
}
}
}
}
}