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) error

Emits one event and flushes. Returns the underlying write error, typically a client disconnect, so the caller knows to stop.

func (w *Writer) Ping() error

Emits an SSE comment line as a heartbeat, so idle proxies do not close the connection.

Hub

func NewHub() *Hub

Builds 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) int

Returns the current subscriber count for a topic.

ServeStream

func ServeStream(w http.ResponseWriter, r *http.Request, hub *Hub, topic string) error

Subscribes 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.