This page looks best with JavaScript enabled

Server Sent Events - Concepts

 ·  ☕ 4 min read  ·  ✍️ Neeraj Sidhaye · 👀... views

This post describes basics of

  • SSE concepts
  • SSE use cases
  • How does SSE work
  • Message Formats
  • SSE code on Client side and Server side
  • SseEmitter connection keep alive time
  • Auto Re-connect mechanism

SSE Concepts

Server Sent Events are the events ( data ) sent from server to the client over HTTP connection.

This connection is one directional connection from server to client. Meaning that, once the client connects to server, then there after server will send any real-time notifications generated on the server side, to the client.

Client can be mobile app or browser based app, or any client that support HTTP Connection.

SSE use cases

You would have seen SSE use cases around you in day to day life

  1. Continuous update about train time notifications on the display panel on the platform.
  2. Continuous Rolling of Stock updates.
  3. Real time counter increment of your social media ‘likes’ icon and could be more…

How does SSE work

Client initiates a connection to server over http, this can be done by client calling a rest end point on the server, in return, the response should have content-type header values as text/event-stream

This tells the client, that a connection is established and stream is opened for sending events from the server to the client.

In the browser you have a special object called, EventSource, that handles the connection and converts the responses into events.

Message-Formats

SSE only supports text data. Meaning, server can only send text data to the client.
Binary streaming, while possible, is inefficient with SSE. In that case, WebSocket would be good choice for binary data transfer.

SSE code - Client side and Server side

Client Side Code

EventSource object is the core object supported by browser.
To open a connection to the server, client will need to instantiate EventSource object.

1
const eventSource = new EventSource('http://localhost:8080/subscribe/'); 

Browser sends this GET request with accept header text/event-stream.The response to this request, must contain header content-type with value text/event-stream and response must be encoded with UTF-8.

To process these events in the browser an application needs to register a istener for the message event.

The property data of the event object contains the message

1
2
3
4
eventSource.onmessage = event => {
  const msg = JSON.parse(event.data);
  // access your attributes from the msg.
};

Client api supports certain events like open and error. Open event occurs as soon as 200 response is received by client for /subscribe GET call.
Error event is received by client, when there is any network error or server terminates the connection.

Server Side Code

Http Response to the above GET request on /subscribe end point must contain the Content-Type header with the value text/event-stream.

Spring Boot supports SSE by providing SseEmitter object. It was introduced in spring version 4.2 ( spring boot 1.3 ).

Create a spring boot application from start.spring.io and select web as dependency.
You can have a controller with rest end point GET with /subscribe allows client to establish connection.
Another rest end point POST with /event allows us to submit new events on the server.
This POST with /events or similar end point, can be called from any other server side component to send real time notification.

This /event end point, will then send event to connected clients.

Each client connection is represented with it’s own instance of SseEmitter.

One limitation with spring SSE is , it does not give you tools to manage
these SseEmitter instances. So, for this example, I have used a list that stores SseEmitter objects and release objects on errors, completion or timeout scenarios.

SseEmitter object is created as below

1
SseEmitter emitter = new SseEmitter();

SseEmitter connection keep alive time

By default, Spring Boot with the embedded Tomcat server keeps the SSE HTTP connection open for 30 seconds.We can override this 30 seconds via configurations.

spring.mvc.async.request-timeout=50000

this entry will keep the HTTP connection open for 50 seconds. Alternatively, you can directly use SseEmitter constructor to pass this timeout value as below

SseEmitter emitter = new SseEmitter(150_000L); 
//keep connection open for 150 seconds

Auto Re-connect mechanism

The nice thing about Server-Sent Events is that they have a built in re-connection feature. Meaning that, if the connection is dropped due to server error then client will automatically tries to re-connect after 3 seconds.

The browser tries to send reconnect requests forever until he gets a 200 HTTP response back.

It’s a browser feature to wait for 3 seconds and then automatically reconnect.
This 3 seconds of time can be changed by the server by sending a new time value in the retry header attribute together with the message.

A client can be told to stop reconnecting using the HTTP 204 No Content response code.

Did you find this page helpful? Consider sharing it 🙌

Share on

{Neeraj:Sidhaye}
WRITTEN BY
Neeraj Sidhaye
I Aspire to Inspire before I Expire!