Websocket & SSE: The Path to Real-Time
Time, the weird concept, created by us, to describe how changes affect our perception of the World. Even if it is just that, a concept, our lives revolve around it and thus it is important to consider it. Software Engineering and development are not different. Where the internet reigns supreme, it is inconceivable in this day and age, to develop a web-app (or any application for that matter) and click on a reload button/F5/Ctrl+r to get the most recent data. Our applications must be real-time.
What is a real-time application (RTA), you ask?
It’s an application which gives the sense of instantaneity e.g if user A changes some data in the application, this change will be known by all users in the briefest delays, without the need of reloading the application.
Furthermore, the latency criterion which influences the delivery delays of the data on an application (internet, data processing and so on) is quite important when we want to implement a real-time application. Depending on how well we can respect the deadlines, our application falls into one of the three following categories:
- Hard Real-Time, where we must respect every single deadline in our application. Otherwise, it results in a total system failure.
- Firm Real-Time, when missing some deadlines is tolerable. Any data received after a deadline is useless and consequently, the quality of the applications is inversely proportional to the quantity of deadlines missed.
- Soft Real-Time, the usefulness of the data received after its deadline reduces, and so the quality of the system.
And the question which arises is: Where is the Web in all of this? Or to be more precise, where do Web-apps stand for in those three categories?
Well, it should be obvious, Web-apps cannot be placed in first category, since the Web always have delay, and it is nearly impossible to insure every single deadline in our application because of the internet entropy.
A Web-app can, although, be placed in the latter categories.
After all this talk about RTA, it seems that every application, nowadays, must include a real-time component. As already mentioned, we want our applications to be reactive. When some change is made, its effect must ripple through all users using the application. Notifications, chat messages, news feed, etc. All of these are examples of real-time in our applications.
However, building RTAs is not necessarily a piece of cake. This brings added complexity in our architectures since it demands more resources which also implies synchronisation between those. And the way we must handle our data can also be quite tricky (the order between messages, delays, loss and retransmission, etc.).
Building Real-Time Applications
Now, let’s talk business!
How do we build real-time applications?
Funny enough, on an architectural point of view, we already have the basics, Server and Client. However, the tricky part is the communication between them. We already communicate with the server via HTTP requests and the server sends HTTP responses. However, we also want the server to be able to send us messages. Introduce Websockets and Server-Sent Events (SSE).
Websockets and Server-Sent Events are ways of achieving a somehow bidirectional communication path between the server and clients.
Websockets use one TCP connection (per websocket). It is an upgraded HTTP protocol which enables bidirectional communication between a web-client and a web-server with low overhead. (Fair warning, websockets are not here (as of right now) a way to replace HTTP, please do not use websockets to do your usual posts and gets.)
As pros, Websockets offers us a full-duplex communication which passes most firewalls without much reconfiguration. We can exchange any kind of data, and it also has a good security model (origin-based security model).
However, there are still proxies which do not support the protocol, and Websocket Servers need different optimisations when compared to normal web-servers.
SSE, which is often times neglected, are normal HTTP request and responses, much like long-polling without the exaggerated overhead. The first request which must be sent though must have a content type text/event-stream. Once this request was sent and the server acknowledged, it can push messages to the client at will.
As benefits, SSE use common HTTP, reconnection and event-ids are given by the implementation and it is a simple protocol.
Unfortunately, SSE have no binary support and it is limited to the number max o HTTP connections.
Websockets vs SSE
After exposing these both tools, the questions which arise are:
When should I use one or the other?
Is one better than the other?
Well, it depends (it never really is that straightforward, is it?).
Websockets, as already said, are best used when we really want a bidirectional path between the server and the client, typically when we are building a collaborative app, a multiplayer game, a chat, etc.
When we just want to receive updates from our server e.g. notifications, update streams like a feed, SSE are great since they do not require much work and it gets the job done.
Although, we talked about the best way of achieving real-time, there are some other tools which are worth mentioning.
Real-time databases are, as the name implies, databases which are prepared to handle data using the principles of real-time computing, so the data is readily available to be sent to the client if needed and handle more data in general. Examples of these kind of databases are RethinkDB, and Firebase also offers a real-time database.
I think it is quite enough for an article, don’t you ? So, to conclude, when we talked about real-time for the web-apps, the real-time component of the application can only be described as soft or firm and even though, Real-Time is trendy and really useful, it can be difficult to program/maintain it or deal with. Finally both Websockets and Server-Sent Events are ways of achieving real-time in our applications. Choose carefully, sometimes you may need one or the other. If your application requires a full bidirectional connection between the server and the client, then use Websockets. If you only need updates use SSE.
Make sure to check my GitHub repo out, to play with both these tools !
Thank you all for reading this article, please feel free to give any suggestions for further improvements, or corrections.
Written by Yoan Ribeiro