function sse(res, { event, data, id, retry }) { if (id) res.write(`id: ${id}\n`); if (event) res.write(`event: ${event}\n`); if (retry) res.write(`retry: ${retry}\n`); res.write(`data: ${typeof data === "string" ? data : JSON.stringify(data)}\n\n`);}
5. Implementing Event Types
Example: Multiple event names
sse(res, { event: "user.created", data: user });sse(res, { event: "user.updated", data: user });sse(res, { event: "user.deleted", data: { id } });// Client: src.addEventListener("user.created", ...)
6. Handling Client Reconnection
Example: Resume from Last-Event-ID
app.get("/events", async (req, res) => { // standard SSE headers... const since = req.get("Last-Event-ID"); for await (const evt of bus.replay(since)) { sse(res, { id: evt.id, event: evt.type, data: evt.payload }); } // continue streaming new events...});
Warning: Most reverse proxies and load balancers idle out connections at 30–60s. Send a heartbeat comment every 10–20s.
9. Broadcasting Events to Clients
Example: Pub/sub fanout
const clients = new Set();app.get("/feed", (req, res) => { // standard SSE headers... clients.add(res); req.on("close", () => clients.delete(res));});export function broadcast(event, data) { for (const res of clients) sse(res, { event, data });}
10. Closing SSE Connections
Example: Server-initiated close
sse(res, { event: "shutdown", data: { reason: "deploy" } });res.end(); // browser will reconnect automatically per retry: directive