package sse import ( "encoding/json" "fmt" "net/http" "time" "github.com/gin-gonic/gin" ) func Serve(c *gin.Context, sub *Subscription, heartbeat time.Duration) { c.Writer.Header().Set("Content-Type", "text/event-stream") c.Writer.Header().Set("Cache-Control", "no-cache") c.Writer.Header().Set("Connection", "keep-alive") c.Writer.Header().Set("X-Accel-Buffering", "no") c.Writer.WriteHeader(http.StatusOK) flusher, ok := c.Writer.(http.Flusher) if !ok { c.AbortWithStatus(http.StatusInternalServerError) return } fmt.Fprint(c.Writer, ": connected\n\n") flusher.Flush() if heartbeat <= 0 { heartbeat = 25 * time.Second } ticker := time.NewTicker(heartbeat) defer ticker.Stop() ctx := c.Request.Context() for { select { case <-ctx.Done(): return case ev, ok := <-sub.Events(): if !ok { return } payload, err := json.Marshal(ev.Data) if err != nil { continue } fmt.Fprintf(c.Writer, "event: %s\ndata: %s\n\n", ev.Type, payload) flusher.Flush() case <-ticker.C: fmt.Fprint(c.Writer, ": heartbeat\n\n") flusher.Flush() } } }