What are Server-Sent Events?
Server-Sent Events(SSE) is a lightweight & standardized protocol for pushing messages from a HTTP server to a client.
Why do you need Server-Sent Events?
It is generally used to get real-time notifications/messages from the server. We can also achieve the same using websockets which offers bi-directional communication. In contrast, SSE only allows for one-way communication from the server to the client. If that’s all you need, SSE has the advantages to be simpler, to rely on HTTP only and to offer retry semantics on broken connections by the browser.
How do we use it in general?
According to the SSE specification, clients has to initiate the communication & can request an event stream from the server via HTTP. The server responds with the media type text/event-stream which has the fixed character encoding UTF-8 and keeps the response open to send events to the client when available. Events are textual structures which carry fields and are terminated by an empty line
Sample response from server:data: { "inprogresscount": "4" }
event: requestreceived
id: 5
.
.
.
data: { "inprogresscount": "7" }
event: requestreceived
id: 9
Clients can optionally send the last seen event to the server via the Last-Event-ID header, e.g. after a reconnect
How do we use it in spring?
To achieve this in Spring >4.1 version we have three new classes to handle Requests Asynchronously of the Servlet Thread.
ResponseBodyEmitter
SseEmitter
StreamingResponseBody
Flow of events explained
Time for a story
Do not worry I will keep it short!!!
We have a use-case in our legacy application where we need to show the updates to the users in near real-time, this could not be achieved due to the dependencies versions and various other reasons. So, it has been using frequent polling to get the resources from the server. This has many problems, firstly it overloads the server in the cases where there is no actual updates, secondly it happens so frequently that it gives inconsistent server metrics in newrelic/appinsights which might lead to inference of many fallacies.
We had gone through the upgrade of dependencies where spring server-sent events came to the rescue. Now, only when there is actual change in the server, it is being pushed to the client which reduces lot of slack on both the sides.
Quick overview of how it is actually done
I would try to briefly explain the steps involved(steps are numbered & encircled in the picture)
- #1 Client loads the web app and goes through authentication
- #2 Client issues GET request to the server to retrieve SSE instance
- #3 Spring controller receives the request, fetches the server-sent-emitter from some service which maintains the dictionary(by all means guard this state for multithreading) of server-sent-emitter based on the client
Note: Once we return from a controller handler method, container thread is released and can serve more upcoming requests.
Because we have multiple artifacts in our application, we need eventbus to communicate between artifacts for which activemq is used. - #4 By virtue of some action by a different client, our server resources gets modified(needs to posted to all interested clients – happens in artifact A) during which we enqueue some message denoting the change & its relevant data.
- #5 & 6 Activemq listener receives the message, handles the message and then use parallel streams to the appropriate server-sent-emitters filtered out from the dictionary.
On the client side, we use the angularjs service to create eventsource object and perform the required updates.
Java Development
Finally, If you are in need of Java Software Development you can reach us using our Contact Form or by calling us on +353 (0)1 818 2949
We have been developing web and mobile apps for many years over a wide range of industries.
An experienced staff member will be happy to give you a no-obligation consultation. They will go through what you require and put together the most efficient and cost-effective solution for you.
Greenfinch Technology