What are Server-Sent Events (SSE)?

Server-Sent Events (SSE), are a way of pushing messages to a client (or browser) without having to poll for the information.  Once an initial connection is established between the client and server, messages can be streamed to the client but the connection only works one way, meaning messages cannot be streamed back to the server.  SSE are standardized as part of HTML5 by the EventSource API and therefore enjoy ubiquitous support amongst all modern browsers.

How do Server-Sent Events work?

Server-Sent events are always initiated by the client establishing a connection with the server.  Once the connection is established, data is streamed to the client from the server until the connection is terminated by the client.

Server Sent Events exchange
Server Sent Events exchange

Above: A client initiates a connection, after which Server-Sent Events are streamed back to the client until it closes the connection.

When should you use Server-Sent Events?

Server-Sent Events are a great choice when dealing with real-time data that does not require interactivity.  Any scenario that could be described as ‘listen for updates’ would be a good candidate for SSE, for example:

  • Receiving a stream of social interactions at a concert

  • Receiving position updates for in-flight aircraft

  • Receiving stock prices and trade information

  • Populating a dashboard of Wikipedia edits

This last example is a fairly common example of Server-Sent events since Wikimedia publishes a public server-sent event stream of updates.

Should you use Server-Sent Events or Polling?

Server-Sent events are more efficient than polling when sending large amounts of data because multiple messages can be sent after the initial connection, but the server cannot automatically detect when a client disconnects, and data can only be sent one way.

For all types of polling, including HTTP polling, the client needs to initiate a connection whenever it wants to receive data whereas Server-Sent events allow data to be streamed over a single connection once it is established.

Polling - Long Polling and Server Sent Events
Polling - Long Polling and Server Sent Events

Above: Comparison of HTTP Polling, HTTP Long Polling, and Server-Sent Events

For streaming use cases such as a social media update stream then server-sent events are a good choice but if the restrictions of a single largely stateless data stream are too much, then you should consider HTTP Long Polling or another technology such as WebSockets

EventSource: An implementation of Server-Sent Events

The EventSource API is the standardized implementation of Server-Sent Events available in all modern web browsers and also as both client and server library implementations in many languages.

Client EventSource implementation

A basic implementation of a client using the EventSource API will be as follows:

Register to receive events by declaring an EventSource object, initialized with the source of the stream

const eventSource = new EventSource('http://mysource.com/stream');

The onMessage event can then be declared to perform some action on the message.

eventSource.onmessage = (event) => { console.log(event.data); }

By default, if the connection between the client and server closes, for example when the connection is lost, the connection is restarted.  To explicitly terminate the connection there is a close method.

eventSource.close();

Event fields

The code listed previously is for the most basic example but it is possible to specify and filter on custom events.  When scaling Server-Sent events you can use different event types to allow clients to only listen for what they are interested in.

The event fields a server can specify when sending the event are as follows:

  • Event: The type of event being defined.  A client can choose to listen for only certain types of events, useful for scaling server-sent events. 

  • Data: The string data within the event.

  • Id: The ID of the event.

  • Retry: Specify a custom reconnection time if the connection is lost.  By default, this will be 3000ms.

Events themselves are delimited by a double newline character, “\n\n

If the event type was defined, rather than use onmessage() you should listen for events using addEventListener(), as follows:

eventSource.addEventListener("eventType", (event) => { console.log(event.data); });

Server EventSource implementation

Many EventSource server implementations exist but they all adhere to the EventStream standard.

In pseudo-code:

While (true) {

SEND "event: temperature\n"

SEND 'data: {"sensor":"NNW1","val":_sensor_reading_}'

SEND "\n\n"

}

Notice that the type of event is specified (a temperature sensor reading), it is possible to specify JSON data in the event message and each message is delimited by a double newline character.

Scaling Server-Sent Events

Server-Sent Events have a notable limitation when running over HTTP/1.x.  There is a limit to the maximum number of open connections, currently set very low (6).  This limit applies per browser + domain, meaning you can open 6 SSE connections across multiple tabs to www.domain.com and another 6 to www.domain2.com.  For more information please see the Mozilla developer pages for SSE.

WebSockets and Server-Sent Events: How do they compare?

WebSockets and Server-Sent Events have a lot in common: both allow a server to push data to a client (or browser) efficiently and present an alternative to the client polling the server whenever an update is needed.  

Both WebSockets and SSE also provide low-latency solutions but there are differences:

  • WebSockets are bi-directional whereas once the connection is established, SSE can only send data (events) from the server to the client.

  • SSE is based on HTTP and HTML5 standards, which means the protocol is more compliant with network infrastructure (proxies, firewalls, and load balancers) which have been known to block WebSockets.

  • SSE does not provide the server with a way to detect that a client has disconnected before data is sent, whereas WebSockets can detect disconnection at either end. 

Consuming Server-Sent Events with PubNub

PubNub is protocol agnostic, as explained in this support article, so you cannot connect to PubNub using the EventStream API.  

A Server-Sent Event stream can be easily ingested by PubNub and distributed through PubNub’s infrastructure.  If you would like to learn more about integrating PubNub with Server-Sent Events please see our Real-Time Data Streaming tutorial which walks you through consuming the Wikimedia real-time stream and distributing it with PubNub.  Our Real-Time Streaming Demo also shows the Wikimedia event stream being consumed. 

MORE FROM PUBNUB
What is a WebSocket?

What is a WebSocket?

WebSockets are a transport protocol defined by a persistent, bidirectional communication channel between server and client that takes place over a single TCP socket connection.
HTTP Long Polling

HTTP Long Polling

HTTP Long Polling is a variation of standard polling that emulates a server pushing messages to a client (or browser) efficiently.
What is ngrok?

What is ngrok?

ngrok allows developers and teams to easily expose local servers.

Talk to an expert