package serverevents import ( "fmt" "net/http" ) type Config struct { Connected func(chan string) Disconnected func(chan string) } type Handler interface { http.Handler Broadcast(message string) } type handler struct { clients map[chan string]bool Connected func(chan string) Disconnected func(chan string) } func New(config *Config) Handler { return &handler{ make(map[chan string]bool), config.Connected, config.Disconnected, } } func (sse *handler) Broadcast(message string) { for client := range sse.clients { client <- message } } func (sse *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") w.Header().Set("Access-Control-Allow-Origin", "*") client := make(chan string) sse.clients[client] = true if sse.Connected != nil { sse.Connected(client) } defer func() { close(client) delete(sse.clients, client) if sse.Disconnected != nil { sse.Disconnected(client) } }() flusher, _ := w.(http.Flusher) for { select { case message, ok := <-client: if !ok { return } fmt.Fprintf(w, "data: %s\n\n", message) flusher.Flush() case <-r.Context().Done(): return } } }