What is Server-Sent Events (SSE) and how to implement it?

Gökhan Ayrancıoğlu
Delivery Hero Tech Hub
5 min readFeb 7, 2022

Server sent events(SSE) is a pushing technology that enables pushing notification/message/events from the server to the client(s) via HTTP connection.

While you are developing real-time projects, there is always a one-question mark on “how to send messages/updates from server to client”. We can talk about three different ways to perform server-to-client updates: Client polling, Web Socket, Server-Sent Events (SSE).

Client Polling

The client sends requests to the server at regular intervals for new updates. Although this technique is not used much nowadays, it can be preferred for some small-medium size projects. It is easy to implement. This technique does not provide a fully-real time system that depends on the request intervals.

In the polling technique, requests are sent and managed by the client side. Requests are sent by the client even if there is no update on the server.

Web Socket

Websocket is a very popular technology that provides bi-directional data transfer for client and server communication on real-time applications. Websocket is not based on HTTP protocol, so it requires additional installation and integrations to use it. It is difficult to implement compared to other technologies that were mentioned above.

Server-Sent Events

SSE is a technology that provides asynchronous communication with event stream from server to the client over HTTP for web applications. The server can send un-directional messages/events to the client and can update the client asynchronously. Almost every browser is supporting the SSE except Internet Explorer :)

Server-sent event (SSE) enables servers to send messages from the server to the client without any polling or long-polling. Let’s take a quick look at the list that SSE can use:

  • E-commerce Projects (notify whenever the user needs the information)
  • Tracking system
  • Alarm/Alert Projects
  • IoT Projects (Alarm, notify, events, rules, actions)
  • Stock Markets (Bitcoin etc.)
  • Breaking news, Sports Score Updates
  • Delivery projects
  • In-app notifications

In short, SSE can be used in all web applications where users need real-near time information.

The server-sent events streaming can be started by the client’s GET request to Server.

GET /api/v1/live-scores 
Accept: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

Accept: text/event-stream indicates the client waiting for event stream from the server, Cache-Control: no-cache indicates that disabling the caching and Connection: keep-alive indicates the persistent connection. This request will give us an open connection which we are going to use to fetch updates. After the connection, the server can send messages when the events are ready to send by the server. The important thing is that events are text messages in UTF-8 encoding.

List of pre-defined SSE field names include:

  • event: the event type defined by application
  • data: the data field for the event or message.
  • retry: The browser attempts to reconnect to the resource after a defined time when the connection is lost or closed.
  • id: id for each event/message
id: 1
event: score
data: GOAL Liverpool 1 - 1 Arsenal
data: GOAL Manchester United 3 - 3 Manchester City

So how to implement this great technology into our projects. Let’s get started with Spring Webflux.

Server-Sent Event Application with Spring Webflux

Spring Webflux is a framework built on Project Reactor that supports reactive, asynchronous, and non-blocking programming to develop web applications. We are going to build a live score application that provides real-time live score updates to the clients via Server-sent events.

  • Mono: A publisher that can contain 0 or 1 event.
Mono<String> stringMono = Mono.just("Hey Gokhan");
Mono<Integer> integerMono = Mono.just(1);
Mono<Object> monoError = Mono.error(new RuntimeException());
Mono<Object> monoEmpty = Mono.empty();
  • Flux: Publisher that can contain 0..N events.
Flux<String> stringFlux = Flux.just("Gokhan", "SSE", "Article");
Flux<Integer> fluxRange = Flux.range(1.5);
Flux<Long> longFlux = Flux.interval(Duration.ofSeconds(1));

First of all, the spring-boot-starter-webflux dependency needs to be added to Gradle or Maven. Now we can build a simple SSE reactive application with Webflux objects. (source codes: Github Repository)

implementation 'org.springframework.boot:spring-boot-starter-webflux'

We are building a live-score application so we need to define our property to the LiveScore.java class.

Let’s create a class that provides a publisher with the live-core input and subscribe method for the real-time update to the connected clients.

And now we should provide the endpoint for publishing the live-score and server-sent events for the clients.

The send method will create an event and this event will be published to the clients via server-sent events.

curl --location --request POST 'http://localhost:8080/api/v1/live-scores' \
--header 'Content-Type: application/json' \
--data-raw '{
"homeTeam": "Arsenal",
"awayTeam": "Tottenham",
"homeScore": 1,
"awayScore": 1
}'

The most important part of the project is SSE for live updates. We are building an endpoint that represents the GET HTTP method for the event stream and TEXT_EVENT_STREAM_VALUE as Content-Type and we are providing a live stream with Flux objects which are provided from Spring Webflux.

@GetMapping(path = "/live-scores", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<Object>> consumer()
...

We can build an event using ServerSentEvent that includes all pre-defined methods such as id, data, event, retry and comment.

ServerSentEvent.builder()
.id("id").event("goal")
.data(liveScore).comment("Comment")
.retry(Duration.ofMillis(300))
.build();

Run the application after you clone(from Github Repository) or develop it. Run the following Gradle command for the live-score application that we build:

gradle bootRun

We are ready for the Demo:

Open the browser and hit the URL: http://localhost:8080/api/v1/live-scores The stream of data has the live score be displayed whenever it is published by the server.

Disadvantages

  • One potential downside of using Server-Sent Events is the limitations in data format. Since SSE is restricted to transporting UTF-8 messages, binary data is not supported.
  • When not used over HTTP/2, another limitation is the restricted number of concurrent connections per browser. With only six concurrent open SSE connections allowed at any given time, opening multiple tabs with SSE connections can become a bottleneck. (Credit: Dan Messenger)
ref: Mozilla

Conclusion

Server-sent events is a way of reactively sending messages from a server. Server-sent events is the perfect solution for real-time applications. it is lightweight, fast, easy to implement and it provides low latency.

All source code is available on Github Repository.

— Find me around the web: Twitter, Linkedin, Github

— — 1:1 Superpeer

https://gokhana.dev

--

--

Gökhan Ayrancıoğlu
Delivery Hero Tech Hub

Software Engineer @Yemeksepeti • #Java • #Spring Boot • #Kotlin • #Spark • #Microservices • https://gokhana.dev