flexway
FRENTalk to an expert

Streams: SSE and WebSocket

GuideDevelopersSince version 0.2.0

Markdown

On this page

Streams are relayed without holding: each event arrives when the upstream emits it.

Product side: API gateway; operations side: SSE and WebSocket streams.

Server-sent events

curl -N -H "Authorization: Bearer $TOKEN" -H 'Accept: text/event-stream' https://api.example.com/events
Rule Detail
No total deadline An open stream is not cut by the operation's budget
Silence ends it Past the operator's read timeout without a byte, the stream closes: have the upstream send a heartbeat (: ping) more often
Rate Counted at opening

A browser's EventSource cannot set Authorization. Read the stream with fetch:

const res = await fetch("https://api.example.com/events", {
  headers: { Authorization: `Bearer ${token}`, Accept: "text/event-stream" },
});
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
for (;;) {
  const { value, done } = await reader.read();
  if (done) break;
  handle(value); // split on the blank line that ends an event
}

WebSocket

The upgrade is a request like any other: identity and rate are checked at opening, then the connection outlives the operation's budget.

// A browser sets no header on a WebSocket: the operator decides how the identity arrives (a cookie
// the contract declares, an edge that authenticates). A server-side client sets Authorization:
const ws = new WebSocket("wss://api.example.com/ws", { headers: { Authorization: `Bearer ${token}` } }); // Node (ws)

A broker's event channels (acknowledgements, resumption) are described apart: asynchronous channels.

Next steps