Send your request Join Sii

I want to present the Server Side Events technology implemented using Spring Boot and Angular 16. The article goes with:

  • brief introduction to SSE,
  • implementation of SSE with a Spring Boot (SSE Emitter),
  • implementation of SSE with Angular 16,
  • description of what is going on under the hood,
  • compared with other similar technologies,
  • use cases where SSE can be used.

Enjoy!

A brief introduction to SSE

Server Side Events is a web technology that enables a unidirectional, real-time communication channel between a web server and a client, typically a web browser. In a nutshell – you create a long-lived HTTP connection between a server and a browser, and then the server can send asynchronous messages to the browser without user involvement. This is useful for applications like stock market updates, social media feeds, and collaborative tools where real-time updates are crucial.

Why should I use SSE?

SSE has gained popularity for several compelling reasons:

  • Efficiency – SSE operates over a single HTTP connection without requiring multiple requests (as in short or long polling). This efficiency reduces server load and network overhead.
  • Simplicity – implementing SSE on both the server and client sides is straightforward, as it leverages familiar web technologies like HTML, JavaScript, and standard HTTP protocols. There is no need for third-party libraries or complex configurations! All major web browsers, including Chrome, Firefox, Safari, Edge, and Opera, support SSE. IE is the only major browser that doesn’t support SSE.
  • Real-Time Updates – SSE enables real-time updates from the server to the client, allowing instant notifications of events or changes in state.
  • Fallback Mechanism – SSE gracefully handles scenarios where a client’s browser lacks support for SSE. It automatically falls back to other techniques like long polling, ensuring that your application remains functional across various environments.

Advantages and limitations of SSE

Among the advantages of the solution are:

  • Ease of Implementation Implementing SSE Events for the first time took me around 3-4 hours. It doesn’t require complex libraries or additional technologies, simplifying the creation of streaming applications.
  • Low Network Overhead SSE relies on a single, persistent connection to the server, enabling real-time data transmission with a minimal network overhead. You don’t need to open and close multiple connections, positively impacting application performance.
  • No need to constantly request the server once a connection is established as a server-client, you don’t need to constantly request the server if some business status has been changed. When the server changes its status, it can directly send you the event with details of what has changed.
  • Error Handling backend SSE implementation and frontend EventSource provide an API that helps us handle unforeseen situations easily.

Disadvantages of the solution include:

  • Limit of maximum open connections when not used over HTTP/2, SSE suffers from a limitation to the maximum number of open connections, which can be especially painful when opening multiple tabs, as the limit is per browser and is set to a very low number (6).
    When used over HTTP/2 protocol, the maximum number of simultaneous HTTP streams depends on the server and client configuration but, by default, is set to 100.
  • Unidirectional Communication SSE technology enables communication only from the server to the client. It creates limitations, so it may not be the best choice for more complex, interactive applications where bidirectional communication or frequent client-server interactions are needed. On the other hand, unidirectional communication is safer, as the stream of events goes from the server to the user.

Implementing the Spring Boot Server

To present the capabilities of Server Side Events technology, I’ve created a simple app that monitors business processes.

The business logic of the backend system is simple. We have defined 3 three paths:

  • Happy path,
  • Warning path,
  • Error path.

Whenever a monitoring request is made, the system randomly picks and follows one of the paths. Simulates a sample business process that sends status events whenever its state changes.

The working system is below:

Business Process Monitoring
Fig. 1 Business Pocess Monitoring

Application structure:

Application structure:
Fig. 2 Application structure

Controller handling SSE

Plain RestController exposes SseEmitter on GET request. SseEmitter is a class of Spring MVC. It will be exposed over HTTP with a content type as text/event stream. Thus, a browser can request and handle it as an EventSource.

When a request reaches this method, the SSE Event Processor service creates a new SSEEmitter and starts an asynchronous monitoring process.

code

Processor handling Server Side Events

code

This service keeps all created emitters. During the creation process, a new SseEmitter object is created and then stored in a Map.

code

During sending an event, the SseEmitter object is retrieved from the map, and the send method is invoked with an event message. Object SseEventModel is a custom model created for this application.

If the client aborts the connection and the server wants to send a new event – ClientAbortException is called.

code

The process ends when the termination event is sent, and the connection is completed.

For that, I’ve used a message with the flag finished set to true – the client then can handle the connection appropriately.

Business Process Monitoring

This service simulates an ongoing process that is monitored, and the events are sent.

We have defined 3 constant paths:

  • Happy path,
  • No data,
  • Error Path.
code

Simulation of the monitoring process is just picking randomly a path defined above and waiting after every notification.

code

Sending an event is done by calling SseEventProcessor.

code

Implementing the Angular Client

We can obtain an EventSource exposed by the server by simply calling the constructor of the EventSource class. Every modern browser supports this class.

Server-sent events
Fig. 3 Server-sent events
code

We can define three types of handlers for an event source:

  • onmessage – function will be invoked upon the message’s arrival,
  • onerror – will be invoked when the error occurs,
  • onopen – will be invoked when the connection will be opened.

Let’s break down the piece of code responsible for receiving the message:

code

When the event comes, we extract its data, only text in JSON format. We’re closing the connection when the finished event is sent. If not, we’re using messageSubject$ to push the received message.

MessageSubject$ is an Angular’s Subject, which can then be subscribed to display elements on the screen.

ProcessMonitoringService exposes 3 public methods:

  • startMonitoring,
  • getMessageObservable – responsible to return messageSubject$ as an observable,
  • stopMonitoring.
code

I’ve assumed that the connection will be open for different users. For demo purposes, I’ve generated a random user ID to pass as a parameter in creating a Server Side Event Connection request. Then, we can subscribe to the messages in the component and display them to the user.

The component handling the view simply keeps processes as an array, which is updated every time a message is received.

code

We employ the NgZone service to automatically update the component view on the arrival of a message. Without this, we would have to rely on user interaction to display the message correctly. Full code for the frontend and the backend application is available on GitHub.  

Under the hood

But how does it work under the hood?

At the beginning, the browser is opening the connection:

The connection
Fig. 4 The connection

The diagram below illustrates the life cycle of an event source:

The life cycle of an event source
Fig. 5 The life cycle of an event source

The connection is kept open until the proper event completes the connection.

In the browser, we’re able to see incoming events:

Incoming events
Fig. 6 Incoming events

We see that the last message has a finished flag set to true. This way, in the code, we’re able to handle closing connections on the client side more gracefully:

code

But what happens if we lose the connection? Simulating that the server is down after successfully obtaining the connection, we can see that the browser, by default, automatically tries to reconnect to the source:

Automatically reconnection
Fig. 7 Automatically reconnection

Disclaimer – this situation happens if we don’t handle closing the connection in case of failure.
In my example of process monitoring, I’ve handled this case by closing the connection in case of failure:

code

Nevertheless, the behavior of automatically reconnecting can be different among different types of browsers; thus, I recommend handling reconnecting with EventSource manually.

Security with EventSource

EventSource mechanism enables us to provide a withCredentials flag into the constructor.

code

When withCredentials is true, the browser will include cookies and HTTP headers in SSE requests, such as the Authorization header. This enables user authentication and authorization on the server, similar to standard HTTP requests.

Comparing SSE with other technologies

Short Polling

It involves clients making frequent, regular requests to the server for updates. These requests are usually quick and lightweight, making Short Polling a simple solution. However, it can lead to higher network and server resource consumption, as clients consistently ask for updates, even when no new data is available. This constant “polling” can be inefficient and strain the client and server unnecessarily.

  • Protocol: HTTP,
  • Connection type: frequent queries for updates,
  • Performance: excessive network traffic because the client needs to ask the server for updates.

Long Polling

Long Polling is a variation of the polling method designed to mitigate some inefficiencies associated with Short Polling. With Long Polling, clients request the server, and the server holds the request open until new data is available or a timeout occurs. The server responds to the client’s request once data becomes available or the timeout is reached. This approach reduces the constant back-and-forth polling of Short Polling, but it might not be as efficient as more modern solutions like WebSockets or SSE.

  • Protocol: HTTP,
  • Connection type: persistent client-server connection, the server delays response,
  • Performance: high resource usage on the server as well as on the client side due to frequently opening new connections.

WebSockets

WebSockets provide a more sophisticated and efficient means of real-time communication. They offer full-duplex, bidirectional communication, enabling both the client and server to send messages to each other at any time without the need for repeated requests. WebSockets are highly efficient, reducing network overhead and allowing for near-instant data transmission.

  • Protocol: WebSocket protocol,
  • Connection type: full-duplex connection,
  • Performance: highly efficient and fast without excessive delay or continuous server polling.

Comparison of diagram:

Comparision SSE with other technologies
Fig. 8 Comparision SSE with other technologies

Business scenarios where SSE can be used

There’s a huge area where unidirectional communication between servers and clients can be used.
Here are some examples of how Server Side Events can be used.

  • Social Media Feeds – instantly deliver posts, comments, and notifications to users,
  • Sports Updates and Scores – live notifications, up-to-date scores,
  • Live updates for financial markets – providing real-time updates on stock prices and currency exchange rates,
  • monitor system processes and provide the user with the actual state of the process.

Conclusion

As you have seen, server-side events can be effectively used in vast business scenarios.

I hope this article has shown you how to use SSE technology and introduced you to this type of communication. I hope this helps you handle use cases in your system more effectively!

Full code is available on GitHub.

Sources

***

You can also find another article by the author on our blog: NGXS vs NgRx – comprehensive comparison of Angular Redux libraries

5/5 ( votes: 4)
Rating:
5/5 ( votes: 4)
Author
Avatar
Witold Drożdżowski

He has been working in software engineering for 5 years. At Sii, he serves as a Fullstack Developer, specializing in Java and Angular technologies. During his work, he places significant emphasis on the quality and performance of the products he creates. After hours, he enjoys designing applications from the UX/UI perspective and playing board games

Leave a comment

Your email address will not be published. Required fields are marked *

You might also like

More articles

Don't miss out

Subscribe to our blog and receive information about the latest posts.

Get an offer

If you have any questions or would like to learn more about our offer, feel free to contact us.

Send your request Send your request

Natalia Competency Center Director

Get an offer

Join Sii

Find the job that's right for you. Check out open positions and apply.

Apply Apply

Paweł Process Owner

Join Sii

SUBMIT

Ta treść jest dostępna tylko w jednej wersji językowej.
Nastąpi przekierowanie do strony głównej.

Czy chcesz opuścić tę stronę?