Getting to know Server-Sent Events (SSE)

Internet technology uses a request/response paradigm that enables a client to request for information and a server to respond. WebSockets, polling and Server-Sent Events are three different technologies that define how browser and client can communicate with each other. In this blog post, we'll focus primarily on the last category, also known as SSE or EventSource. We'll explain what they are, how they work and how they are used in practice.

What are Server-Sent Events?

Before we dive into the specifics of SSE, let's start by examining what SSE is and what it's used for. The name Server-Sent Events is mostly self-explanatory: it’s a technology standard that allows server-to-client streaming of text-based event data over a HTTP connection. The idea is to have the browser receive data automatically from the server without explicitly having to poll for it. SSE makes working with real-time data simple and efficient, using just one, long-lived HTTP connection.

A specific feature of SSEs is that they’re mono-directional, which means that data communication only happens one-way, in this case from the server to the client. This feature comes in handy for use cases where the client doesn't need to send any data and only requires updates through server actions. In this sense, SSE differs from WebSockets that are bi-directional and enable near real-time updates in both directions.

SSE forms part of the HTML5 specification: the official API is named Server-Sent Events EventSource API, hence the popular term ‘EventSource’. It is natively supported in almost all browsers, however Internet Explorer and Edge being the main exceptions. SSEs are sent over traditional HTTP, so there’s no need for additional protocols or server implementations. The SSE standard provides multiple out-of-the-box features that WebSockets lack, such as reconnection handling.
There are many use cases for SSE. As stated above, SSE is generally used for displaying data updates, such as price information or the availability of products and services on a website. It’s also used for chat applications, news updates and automated push mechanisms.

Components of SSEs

After this quick introduction, let's have a better look at the two components that make up SSEs. Next, we’ll describe how they work together using some coding examples. In general, we can distinguish two components that, when combined, enable SSE technology:

  1. The EventSource API
  2. The Event Stream Protocol

The EventSource browser interface enables the client to receive push notifications from the server as DOM events, while individual updates are delivered through an “event stream” data format.

These components both enable an efficient and cross-browser implementation of XHR streaming, but letting the browser handle all connection management and message parsing.

In the browser, the EventSource API that performs the following tasks: manage the server connection, parse the received data incrementally, identify message boundaries and let the browser fire a DOM event to notify the application. A data stream can be terminated when finished, or resumed using the API’s auto-connect functionality in case the connection is dropped unexpectedly.

Event-stream data (or Server-Sent Events messages) consists of a simple stream of text data encoded in UTF-8. Its specification defines different data fields that are separated by a pair of newline characters: even, data, ID and retry. The data field holds the actual message content that is pushed to the client. Because the data format is well-defined, the EventSource API can do all the work in the browser.

Getting started with SSE

Let’s start with a quick example of an application that uses SSEs. We’ll look at how SSEs are implemented on the client side. The client can be a mobile app and developed in any language that can handle HTTP connections, while the server side can be coded in any language. But first, we'll look at some examples of Server-Sent Events Messages.

Server-Sent Events Messages
Here is a template for single event messages:

id: <messageId>\n
event: <eventType>\n
data: <event data - plain text, JSON, ... >\n
\n
\n

Using this template, we can create the following message:

id: 99\n
event: price\n
data: 99.99\n
\n
\n

Client-side
Here’s a simple client-side implementation of SSE, taken from MDN Web Docs:

const evtSource = new EventSource('sse.php');
const eventList = document.querySelector('ul');

evtSource.onmessage = function(event) {
  const newElement = document.createElement("li");

  newElement.textContent = "message: " + event.data;
  eventList.appendChild(newElement);
}

In the first line, a new EventSource instance is created, that receives server-sent events from a specified URL: in this case, a page called 'sse.php'. In case of an event, an event handler is run after which the message received is written to a new list element and appended to a list already present in the document.

SSEs for high-performance real-time data streams

In this blog post, we discussed Server-Sent Events, or simply SSEs. They are used for high-performance real-time data streams from server to client. We described what they are and mentioned different use cases where they come in handy: since SSEs are mono-directional, they are best used for applications that don't need to send data from the client to the server. Those applications are better served by using WebSockets. SSEs are sent over traditional HTTP and come with a set of handy features for developers. SSEs consist of an EventSource client API that manages the messages sent by the server that are defined in the Event Stream Protocol. Some short examples showed how a template message can be used for a real example showing real-time data. Finally, a code example illustrated SSE implementation on the client side.