Skip to main content

Overview

The sse middleware enables Server-Sent Events (SSE) for real-time server-to-client communication. Unlike WebSocket, SSE is unidirectional and uses standard HTTP.

Installation

Quick Start

Configuration

Examples

Basic Usage

Periodic Updates

Named Events

Full Event Control

Using Broker for Broadcasting

Broadcast Named Events

Custom Options

Resume from Last Event ID

Real-time Notifications

Event Structure

Client Methods

Broker Methods

API Reference

Client Example (JavaScript)

Event Format

Technical Details

Architecture

The SSE middleware implements the W3C Server-Sent Events specification using Go’s HTTP response writer and flusher interfaces. The implementation consists of three main components:
  1. Client: Represents an individual SSE connection with buffered event channels and disconnection handling
  2. Event Loop: Goroutine-based event processing that listens for both new events and client disconnection signals
  3. Broker: Optional multi-client manager for broadcasting events to all connected clients

Connection Lifecycle

  1. Accept Header Check: Validates that the client accepts text/event-stream or */*
  2. Flusher Verification: Ensures the response writer supports HTTP flushing for streaming
  3. Header Setup: Sets required SSE headers (Content-Type, Cache-Control, Connection, X-Accel-Buffering)
  4. Client Creation: Initializes client with event channel (default buffer: 10) and done channel
  5. Event Loop Start: Launches goroutine to process events from the channel
  6. Handler Execution: Runs user-provided handler function
  7. Cleanup: Waits for client disconnection before returning

Event Processing

Events are formatted according to SSE specification:
  • ID field: Optional event identifier for client resumption (id: value\n)
  • Event field: Optional event type name (event: value\n)
  • Retry field: Optional reconnection time in milliseconds (retry: value\n)
  • Data field: Event payload, split by newlines (data: value\n for each line)
  • Terminator: Empty line (\n) signals end of event
Multiline data is automatically split and prefixed with data: for each line.

Broker Implementation

The broker uses a fan-out pattern with three internal channels:
  • Register channel: Adds new clients to the client map
  • Unregister channel: Removes disconnected clients from the map
  • Broadcast channel: Queues events for distribution (buffer: 100)
The broker runs a dedicated goroutine that:
  1. Manages client registration/unregistration
  2. Broadcasts events to all clients without blocking
  3. Skips clients with full buffers to prevent blocking

Concurrency Safety

  • Client send operations use mutex locks to prevent concurrent writes
  • Broker uses RWMutex for safe concurrent access to the client map
  • Done channel is checked before send operations to prevent panics
  • Multiple Close() calls are safe and non-blocking

Last-Event-ID Support

The middleware reads the Last-Event-ID header from reconnecting clients, allowing handlers to resume event streams from a specific point.

Best Practices

  • Use event IDs for client resumption
  • Set appropriate retry intervals
  • Close connections when done
  • Use Broker for multi-client scenarios
  • Keep payload sizes reasonable
  • Handle client disconnections gracefully

Testing