Simplify Real-Time with Server-Sent Events Over WebSockets

- Lire en français

When I started building with the web in 2018, I was fascinated by the real-time feature. Imagine, someone changes something on a page and the change is instantly visible for everyone. It was like magic for me.

I later learned that this magic comes with the cost of complexity.

At that time, I was learning Express, and building a simple web server was already a challenge.

The First Time

Later, for a school project, I had to build a very simple dashboard to manage IoT devices, everything from scratch. Real-time was a requirement to broadcast the state of the devices from the server to every connected client.

I searched on the internet and every blog post, every tutorial was talking about WebSocket. So, maybe that's the way to go. For this project, I learned and used Socket.IO. The project is on GitHub at raspiot.

During the presentation, the demo effect touched me and everything was not working as expected.

With a Framework

I also tried to build a web application for students of my school to manage mentoring between students. I was still a beginner but projects are the best way to learn so I jumped into it.

I used Feathers, the API and real-time application framework. It was probably too easy, so I decided to use Vue for the frontend with Feathers-Vuex.

I never experienced something so hard for absolutely no value to my project. In retrospect, I think I wanted real time because it was fashionable (clearly, not a good reason).

It was so complex that I never finished it.

WebSocket Is Complex

On the web, we use a protocol called HTTP. The request from a browser to a server is using HTTP.

HTTP
HTTP

WebSocket is not HTTP. WebSocket is a protocol on its own. This is very important to know because this has consequences on how we can use it.

WebSocket
WebSocket

First, WebSocket is not native on Node.js. We have to use an external library to use it. This could become a big deal if we have to integrate it into a complex project.

Second, WebSocket does not handle reconnection. If the connection is lost, there is no built-in mechanism to reconnect. We have to handle it ourselves. In another way and despite its native support in browsers, we have to use it with a library to handle reconnection. This starts to be a lot of complexity and code to maintain.

Finally, WebSocket is not HTTP, and in your web server, you will need to handle two protocols and create a bridge between them. The bigger part is about authentication and authorization. This could result in a lot of logic to create and maintain despite the fact that we could already have an authentication logic for HTTP. This also implies having a custom logic on the client to handle authentication and authorization. This is because HTTP is stateless and WebSocket is not.

The thing I would love to hear when I was starting with WebSocket is that not every data needs to be real-time and simpler things are better than nothing.

The Other Way

The first time I heard about this tech was on a stream of Romain Lanz. He is a maintainer of Adonis and masters the subject.

Sometimes, real-time can have value for a project that has charts, data visualization, information, asynchronous tasks, or even a chat. But do you see the thing that all of these features have in common?

The client does not send, or few, information. Furthermore, the query time, between the client and the server, is not critical. So why would we need a bidirectional communication? And that does not interop well with HTTP? In 2024, I do not know.

Server-Sent Events

Server-Sent Events (SSE) is a technology that allows a server to send events to a client. It is a unidirectional communication from the server to the client.

SSE
SSE

The client asks for a resource using the EventSource API and the server responds with a stream. This is an HTTP connection but that stays open to allow the server to send data to the client. Simple, right?

Bonus, this handle automatically reconnection without extra code.

On the internet, we can often read that SSE is bad, the client can't send data to the server. But do these people forget how internet works? Do they forget <form> or XMLHttpRequest? Of course, the client can still send data to the server. Today, SSE does not have huge drawbacks.

One day, we will build a simple chat using SSE and a form to send messages to demonstrate how simple and enjoyable the web can be.

In reality, there is a historical reason why WebSocket was better than SSE but that's not more the case in 2024 thanks to HTTP/2.

Using Server-Sent Events

For a game, WebSocket could be the best option to avoid the handshake between the client and the server.

Finally

I think that we should always ask ourselves if we really need an instant bidirectional communication. If we do not need it, we should use SSE. It's simpler, it's HTTP, and it's powerful. Always weigh pros and cons before choosing, even if it's the most popular choice.

So, will you use SSE in your next project that needs real-time?

It's possible to use SSE directly within our application since it's just HTTP. It's also interesting to know that Mercure exists and can be useful for more complex projects.

Support my work
Follow me on