SSE
The server/sse package with Event, Writer, Hub, and ServeStream.
The server/sse sub-package streams Server-Sent Events. Import it as sse. Writer emits events on one connection, Hub fans out to subscribers by topic, and ServeStream ties a topic to a handler.
Event
type Event struct {
ID string
Type string
Data string
}One SSE record. ID is optional, Type maps to the SSE event: field, and Data is the payload. An empty Type emits a default message event.
func JSONEvent(eventType string, payload any) (Event, error)Marshals payload into the event's Data, returning an error when marshaling fails.
Writer
func NewWriter(w http.ResponseWriter) (*Writer, error)Wraps a response writer. Returns an error when the writer cannot flush, since SSE is impossible without flushing.
func (w *Writer) Start()Writes the streaming headers and flushes. Safe to call more than once.
func (w *Writer) Write(ev Event) errorEmits one event and flushes. Returns the underlying write error, typically a client disconnect, so the caller knows to stop.
func (w *Writer) Ping() errorEmits an SSE comment line as a heartbeat, so idle proxies do not close the connection.
Hub
func NewHub() *HubBuilds an empty hub.
func (h *Hub) Subscribe(ctx context.Context, topic string, buffer int) (<-chan Event, func())Registers a subscriber on a topic. The returned channel receives every event published to the topic. Cancel through the returned func or by cancelling ctx to unsubscribe. buffer controls how many events may pile up before the subscriber is considered slow and dropped.
func (h *Hub) Publish(topic string, ev Event)Sends an event to every subscriber of the topic. A subscriber whose channel is full at delivery time is considered slow, has its channel closed, and is dropped, so a slow consumer never blocks the producer.
func (h *Hub) Subscribers(topic string) intReturns the current subscriber count for a topic.
ServeStream
func ServeStream(w http.ResponseWriter, r *http.Request, hub *Hub, topic string) errorSubscribes the request to a topic and streams every event over SSE until the request context is cancelled. Sends a heartbeat ping every 15 seconds so proxies do not idle out the connection.