Server-Sent Events
Server-Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via HTTP connection. Each notification is sent as a block of text terminated by a pair of newlines (learn more here).
Usage
To enable Server-Sent events on a route (route registered within a controller class), annotate the method handler with the @SSE()
decorator.
@SSE('sse')
sendUpdate(): EventTarget {
const eventTarget = new EventTarget();
let id = 0;
const interval = setInterval(() => {
if (id >= 4) {
clearInterval(interval);
const event = new SSEMessage({
retry: 1000,
id: `${id}`,
data: 'close',
event: 'close',
});
eventTarget.dispatchEvent(event);
return;
}
const event = new SSEMessage({
retry: 1000,
id: `${id}`,
data: 'world',
event: 'hello',
});
eventTarget.dispatchEvent(event);
id++;
}, 100);
return eventTarget;
}
info Hint The
@SSE()
decorator andSSEMessage
class are imported from the@danet/core
, whileEventTarget
is a web standard class.
warning Warning Server-Sent Events routes must return an
EventTarget
.
In the example above, we defined a route named sse
that will allow us to propagate real-time updates. These events can be listened to using the EventSource API.
The sse
method returns an EventTarget
that dispatch multiple SSEEvent
(in this example, it emits a new SSEEvent
every second). The SSEEvent
takes a SSEMessage
object as argument should respect the following interface to match the specification:
export interface SSEMessage {
data: string | object;
id?: string;
event?: string;
retry?: number;
}
With this in place, we can now create an instance of the EventSource
class in our client-side application, passing the /sse
route (which matches the endpoint we have passed into the @SSE()
decorator above) as a constructor argument.
EventSource
instance opens a persistent connection to an HTTP server, which sends events in text/event-stream
format. The connection remains open until closed by calling EventSource.close()
.
Once the connection is opened, incoming messages from the server are delivered to your code in the form of events. If there is an event field in the incoming message, the triggered event is the same as the event field value. If no event field is present, then a generic message
event is fired (source).
const eventSource = new EventSource('/sse');
eventSource.onmessage = ({ data }) => {
console.log('New message', JSON.parse(data));
};
Example
A working example is available here.