Using NodeJS for uni-directional event streaming (SSE)
Recently I came across a relatively old HTML5 feature called SSE (Server-Sent Events) which, as the name implies, are used to listen to events sent by the server. Which means, the connection is uni-directional, unlike WebSockets.
It has been over-shadowed by the shining, feature-full, all-browser-compatible WebSockets so far. But it can be very useful in situations where bi-directional communication is not a requirement and we need to avoid long-polling.
⚡️ P.S: Read this if you’re looking to add push notifications to NodeJS or Electron apps.
What are Server Sent Events?
In its essence, the SSE feature is quite simple. You need your server to send a specific header, implying it supports the feature, and keep the connection open, i.e; keep-alive. Here’s an example of achieving it with express.
Few things to note in the code above are:
- text/event-stream content type header. This is what browsers look for.
- keep-alive header.
- The double new-line characters at the end of data. This indicates the end of message.
Using SEE in a standard web (DOM) environment is a piece of cake. You just have to use the EventSource interface available globally in the window context.
Consuming SSE in NodeJS
But let’s say we want to listen to these events in node environment instead of browser, how would we go about doing that?
Well that, as it turns out, is also simple. All we have to do is to make a GET request and keep listening for new data being sent.
But… if we are listening to those events in a plain HTTP way, without following any specifications then why are we sticking to the protocol while sending them?
Well that, my friend, is also not required if you are listening to the events in a non-DOM environment. You are free to use whatever headers you want as long as the connection is kept alive. To ensure this:
- Send a ‘keep-alive’ header
- Send status 200, not 204
- Do not terminate after sending data. In http/express, simply use .write() instead of .send().
Custom protocol
Here’s an example of sending JSON data every 5 seconds.
If you noticed, we didn’t use the text/event-stream header because we’re free to send whatever content type we want since we are not using native browser API to listen for events. Also, no double new-line characters at the end of data!
We can use the same code to listen to them without any change.
I can think of a many scenarios where SSEs would make sense. For example, live updates, score updates, stocks, session change, etc.
👉🏼 You can follow me on Twitter for more programming stuff: @moinism
This article was written and optimized in INK