A Look at Server-Sent Events
A Look at Server-Sent Events
Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
You have 2 free member-only stories left this month. Sign up for Medium and get an extra one
Server Sent Events are a standard allowing browser clients to receive a stream of
updates from a server over a HTTP connection without resorting to polling. Unlike
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 1/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
WebSockets, Server Sent Events are a one way communications channel - events flow
from server to client only.
You might consider using Server Sent Events when you have some rapidly updating data
to display, but you don’t want to have to poll the server. Examples might include
displaying the status of a long running business process, tracking stock price updates, or
showing the current number of likes on a post on a social media network.
Architecture
When working with Server Sent Events, communications between client and server are
initiated by the client (browser). The client creates a new JavaScript EventSource object,
passing it the URL of an endpoint which is expected to return a stream of events over
time.
The server receives a regular HTTP request from the client (these should pass through
firewalls etc like any other HTTP request which can make this method work in situations
where WebSockets may be blocked). The client expects a response with a series of event
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 2/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
messages at arbitrary times. The server needs to leave the HTTP response open until it
has no more events to send, decides that the connection has been open long enough and
can be considered stale, or until the client explicitly closes the initial request.
Every time that the server writes an event to the HTTP response, the client will receive it
and process it in a listener callback function. The flow of events looks roughly like this:
Message Format
The Server Sent Events standard specifies how the messages should be formatted, but
does not mandate a specific payload type for them.
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 3/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
id: A unique ID for this event (optional). The client can track these and request that
the server stream events after the last one received in the event of the client
becoming disconnected from the stream and reconnecting again.
event: Specifies the type of event in the case where one event stream may have
distinctly different event types. This is optional, and can be helpful for processing
events on the client.
data: The message body, there can be one or more data key/pairs in a single event
message.
Here’s an example event that contains information about Qualcomm’s stock price:
id: 99\n
event: stockTicker\n
data: QCOM 64.31\n
\n
\n
In this case, the data is simple text, but it could equally be something more complex such
as JSON or XML. The ID can also be any format that the server chooses to use.
Event handler callback functions can then be registered to handle events with a specific
type (event key/value pair is present). These handlers are registered using the
addEventListener method of the EventSource object.
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 4/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
// Declare an EventSource
const eventSource = new EventSource('http://some.url');
In the callbacks, the message data can be accessed as e.data. If multiple data lines
existed in the original event message, these will be concatenated together to form one
string by the browser before it calls the callback. Any newline characters that separated
each data line in the message will remain in the final string that the callback receives.
Important: The browser is limited to 6 open SSE connections at any one time. This is
per browser, so multiple tabs open each using SSEs will count against this limit. See a
discussion on Stackoverflow here for more details. Thanks to Krister Viirsaar for
bringing this to my attention.
Respond with one or more valid server sent event messages, using the correct
message format.
Tell the client that the Content-Type being sent is “text/event-stream” indicating that
the content will be valid server sent event messages.
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 5/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
Tell the client to keep the connection alive, and not cache it so that events can be
sent over the same connection over time, safely reaching the client.
Code for a basic example of a server in Node.js that does this and sends an event
approximately every three seconds is shown below.
let id = 1;
This closes the HTTP connection — the server should detect this and stop sending
further events as the client is no longer listening for them. If the server does not do
this, then it will essentially be sending events out into a void.
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 6/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
When the server realizes that the client has closed the HTTP request, it should then close
the corresponding HTTP response that it has been sending events over. This will stop the
server from continuing to send events to a client that is no longer listening. Assuming
the server is implemented in Node.js and that request and response are the HTTP
request and response objects then the server side code looks like:
request.on('close', () => {
response.end();
console.log('Stopped sending events.');
});
Sending a final event containing a special ID and/or data payload that the
application code running in the browser recognizes as an “end of stream” event. This
requires the client and server to have a shared idea of what that ID or payload looks
like.
AND by closing the HTTP connection on which events are sent to the client.
The client should then call .close() on the EventSource object to free up client side
resources, ensuring no further requests are made to the server.
Assuming the server is written in Node.js, server side code to end the event stream
would look like this (response is the HTTP Response object):
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 7/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
And the client should listen for the agreed “end of event stream” message (in this
example it will have an eventId -1):
Browser Support
Server Sent Events are supported in the major browsers (Chrome, Firefox, Safari), but
not yet in MS Edge where this feature is currently “under consideration” for
implementation (details here).
Chrome currently appears to have the best debugging support — if you select an XHR
request that is receiving Server Sent Events in the Network tab, it will format the
messages for you and display them in a table:
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 8/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
If you want to use Server Sent Events in MS Edge or Internet Explorer, there are polyfills
available that mimic the functionality. One example is Yaffle, whose documentation also
contains a list of alternative implementations.
A Quick Demo
The image below shows a simple browser application that is receiving Server Sent
Events from a Node.js server. The server sends a randomly generated stream of events
that can have one of four event types. Each event type contains a different type of
payload:
The client listens for each event type using a separate listener function for each, and
updates the area of the page corresponding to that event type on receipt of an event.
Additionally, event data is logged to the logging area across the bottom of the page and
to the browser’s Javascript console.
The server will stop sending events after 30 have been sent, or if the user presses the
“Stop Events” button before then.
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 9/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
If you want to grab the complete code for this project and use it yourself, it’s available on
GitHub. You’ll need Node.js installed on your machine, and setup instructions are
included in the project README.
The browser will automatically attempt to reconnect to an event source if the connection
is dropped. When it does, it will send the ID of the last event that it received as HTTP
header “Last-Event-ID” to the server in a new HTTP request. The server can then start
sending events that have happened since the supplied ID, if that is possible for server-
side logic to determine.
The server may also include a key/value pair in the event messages that tells the client
how long to wait before retrying in the event of the server ending the connection. For
example, this would specify a five second wait:
id: 99\n
event: stockTicker\n
data: QCOM 64.31\n
retry: 5000\n
\n
\n
As our demo uses randomly generated event streams, it doesn’t use this capability.
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 10/11
4/7/2021 A Look at Server-Sent Events. Server Sent Events are a standard… | by Simon Prickett | Conectric Networks | Medium
That concludes our quick tour of Server Sent Events. Thanks for reading, if you want to
chat you can find me on Twitter or via the responses here.
https://medium.com/conectric-networks/a-look-at-server-sent-events-54a77f8d6ff7 11/11