package sse import ( "net/http" ) // Handler is the HTTP handler for the GET /api/events SSE stream. // It registers a client with the broadcaster, streams events as they arrive, // and unregisters on disconnect. type Handler struct { bc *Broadcaster } // NewHandler creates a Handler backed by the given Broadcaster. func NewHandler(bc *Broadcaster) *Handler { return &Handler{bc: bc} } // ServeHTTP implements the SSE streaming endpoint. // Flusher is required; clients that do not support flushing receive a 501. func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { flusher, ok := w.(http.Flusher) if !ok { http.Error(w, "streaming not supported", http.StatusNotImplemented) return } // SSE-specific headers 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") // Disable nginx buffering // Write headers immediately flusher.Flush() // Subscribe to the broadcaster ch := h.bc.Subscribe() defer h.bc.Unsubscribe(ch) // Use request context for cancellation when the client disconnects. ctx := r.Context() for { select { case <-ctx.Done(): return case msg, ok := <-ch: if !ok { return } _, err := w.Write([]byte(msg)) if err != nil { return } flusher.Flush() } } }