SSE (Server-Sent Events)
SseActor exposes a Server-Sent Events endpoint. SSE is a
one-way push protocol from server to client over plain
HTTP — simpler than WebSocket, with browser-native
auto-reconnect via the EventSource API.
import { ActorSystem, Props, SseActor } from 'actor-ts';
const sse = system.actorOf( Props.create(() => new SseActor({ host: '0.0.0.0', port: 8080, path: '/events', })), 'sse',);
// Anywhere in the app — push to all connected clients:sse.tell({ kind: 'broadcast', event: 'order-placed', data: JSON.stringify({ orderId: 'o-1' }),});
// Push to a specific connection:sse.tell({ kind: 'send', connectionId: 'conn-42', event: 'private', data: '...',});Browser clients consume via:
const events = new EventSource('http://my-server/events');events.addEventListener('order-placed', (e) => { console.log(JSON.parse(e.data));});Settings
Section titled “Settings”interface SseActorSettings extends BrokerCommonSettings { host: string; port: number; path?: string; // default '/events' keepaliveMs?: number; // default 30_000 — sends comments to keep connections alive}keepaliveMs controls how often the server sends comment frames
(: keepalive) to prevent intermediate proxies from closing
idle connections. 30 seconds is typical.
Event format
Section titled “Event format”SSE has a specific wire format:
event: order-placeddata: {"orderId":"o-1"}id: 42
event: pingdata:The framework constructs this for you:
sse.tell({ kind: 'broadcast', event: 'order-placed', // event name (default 'message') data: JSON.stringify(o), // payload id: String(Date.now()), // optional — used by client for last-event-id reconnect});id is important: when a client disconnects and reconnects (the
browser does this automatically), it sends Last-Event-ID —
your actor can resume from there.
Last-Event-ID for resumable streams
Section titled “Last-Event-ID for resumable streams”class SseActor extends Actor<...> { override onReceive(msg) { if (msg.kind === 'connection-opened') { const lastId = msg.lastEventId; if (lastId) { // Replay events newer than lastId to this client this.replayFrom(msg.connectionId, lastId); } } }}Critical for resumable streams — without it, the client loses events while disconnected. Combined with an event store (or a journal-backed projection), you can build at-least-once push delivery.
When to use SSE
Section titled “When to use SSE”Three primary fits:
- One-way push from server to browser — live feeds, notifications, real-time dashboards.
- When WebSocket is overkill — simpler protocol, easier debugging (it’s just HTTP).
- HTTP-infrastructure-friendly — works through proxies, load balancers, CDNs that don’t understand WS.
For bi-directional comm, use WebSocket. For request/response RPC, use plain HTTP.
Where to next
Section titled “Where to next”- I/O overview — the bigger picture.
- Server WebSocket — for bi-directional.
- BrokerActor base — the shared lifecycle.
- HTTP overview — for plain request/response.