Realtime data streaming using server-sent events(SSE) with react.js and node.js

Realtime data streaming using server-sent events(SSE) with react.js and node.js

Server-sent events(SSE) is a server push technology that enables a client to receive live stream updates from the server via a HTTP connection.

We live in a world where real-time data streaming has become paramount. Real-time data streaming has become a necessity in modern applications because it keeps users notified immediately an event happens. But most of the communication we see on the internet involves a client application making a request to the server which in turn processes the request and send back response to the client. This takes time to process and there are scenarios where a server needs to send data to the client without the client necessarily initiating a request.

This could be done using long polling, websockets, webhooks or server-sent events. Examples of real-time applications include; instant messaging, notification system, online gaming, chat apps, videoconferencing, data streaming, sport updates, stock prices e.t.c. But our main focus in the article is Server-sent events.

Video Tutorial

If you prefer to watch and learn an in-depth tutorial on how to implement server-sent events(SSEs) with react js and node js, here is a full video for you.

Please don't forget to like, comment, subscribe to my youtube channel and share the video with your friends.

Different techniques for client-server communication

Below are some of the techniques used for client server communication

Polling is a technique where the application repeatedly polls data from the server and if you are familiar HTTP protocol, it involves request/response format. It is a traditional technique used by the vast majority of AJAX applications. The trade off with polling is that it creates greater HTTP overhead.

Long polling is a technique in which if the server does not have the data available when a request is made from the client, the server holds the request open until data is available. The server responds when data becomes available, closes the connection and when the client receives the new data, it sends another request to the server again. This cycle is repeated endlessly until either of them closes the connection. The major drawback of this mechanism is once the server has sent the data; it cannot send further data until a new poll request arrives.

WebSockets is a communication protocol that provides full-duplex bi-directional, communication channel over a single TCP connection. This mechanism creates a two-way connection between the server and the client i.e the server can send data to the client and client can send data to the server as well This is great for things like chat apps, instant messaging e.t.c. However, sometimes you need some updates from the server without waiting for the client to repeatedly initiate requests. This includes; friends' online status updates, newsfeeds e.t.c

Server-Sent Events is an HTTP standard that enables a client application to automatically receive updates or event streams from the server once an initial connection has been established. It’s a server push technology that allows client apps to receive data transmission from the server via an HTTP connection and describes how servers can stream data to the client once an initial connection has been established. Server-sent events (SSEs) are unidirectional in nature i.e., only the server can push updates to client. SSE is commonly used to send automatic updates or continuous data streams to a browser client.

The main difference between Server-Sent Events and long-polling is that SSEs are handled directly by the browser and the client app simply has to listen for messages.

SSE contained in the JavaScript EventSource API in order to open a connection to the server to continue receiving event streams. In server-sent events, automatic updates are sent to client rather than pulled from the client.

Server-sent events VS Websockets

WebSockets provide bi-directional, full-duplex communication. It creates a two-way channel where the client can send data to the server and the server can also send data to client. This enables a real-time communication in both directions. This makes it effective for cases like real-time chat apps, games etc.

However, there are some scenarios where client apps don’t need to send data to server but only consumes from the server and this is where server-sent events(SSEs) comes in.

In SSEs, the communication is unidirectional i.e., the server continuously pushed event streams to the client once an initial connection has been established. Examples include; real-time notification systems, sport updates, stock prices, status updates, newsfeed, cryptocurrency updates e.t.c

Server-sent Events implementation

Server sent server can be implemented both server side and client-side environment.

Client-side API

The SSE client API is contained in the EventSource object. When using SSE, the browser will generate an instance of EventSource first to initiate a connection to the server.

In order to detect if a browser supports SSEs, use the code snippet below;

const url = "http://localhost:5000/stream"
//url can be your server url

if ('EventSource' in window) {
  let source = new EventSource(url)
}

Note: The URL above can be in the same domain as the current URL of the application or it can be cross domain as well. When the URL passed to the EventSource constructor is an absolute URL, its origin (scheme, domain, port) must match that of the server.

When a cross-domain is passed as the url, you can specify a second options parameter with withCredentials property to indicate whether to send the cookie & auth headers altogether or not as shown below.

const url = "http://localhost:5000/stream"
//url is your server url

if ('EventSource' in window) {
  let source = new EventSource(url, {withCredentials: true})
}

Eventsource object events

By default, there are three (3) events which include message, open and error to listen on.

  • The open event indicates a successful connection between the server and the client.

  • The error event handles an error connection between the server and the client.

  • The message event is used to listen on live stream data emitted by the server after a successful connection.

SSEs are flexible enough that you can even define your own custom events on the server which you in turn listen on, on the client side.

Below are the three (3) default event listeners with their callbacks.

source.addEventListener('message', function(e) {     
     console.log(e.data);
}, false);
source.addEventListener('open', function(e) {
  // successful connection.
}, false);
source.addEventListener('error', function(e) {
  // error occurred
}, false);

EventSource object properties

Some of the properties of the EventSource instance include;

  • readyState e.g source.readyState

    • readyState value of 0 indicates connecting

    • readyState value of 1 indicates open

    • readyState value of 0 indicates closed

  • url e.g source.url returns connection url

  • withCredentials e.g source.withCredentials show whether or not withCredentials is true.

EventSource object methods

The closed() method can be called to close the connection e.g source.closed()

Server-side implementation

SSE Data format

The SSE data sent by the server to the browser must be UTF-8 encoded text with the following HTTP header.

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

The information sent each time consists of several messages, and each message is separated by \n\n. Each message is composed of several lines of code internally, and each line should be written as follows.

The above field can take the following four values.

  • data indicates the payload to be sent.

  • retry indicates the reconnection time in seconds and it's optional

  • event can be a custom event e.g notification defaults to message when no event is passed

  • id indicates the id of the data to be sent and it's optional

const emitSSE = (res, id, data) =>{
  res.write('id: ' + id + '\n');
  res.write("data: " + data + '\n\n');
  res.flush()
}

const handleSSE = (req, res) =>{
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });
  const id = (new Date()).toLocaleTimeString();
  // Sends a SSE every 3 seconds on a single connection.
  setInterval(function() {
    emitSSE(res, id, (new Date()).toLocaleTimeString());
  }, 3000);

  emitSSE(res, id, (new Date()).toLocaleTimeString());
}

//use it

app.get("/stream", handleSSE)

Using Server-sent events with React.js and Node.js

Implementing server-sent events can be fairly simple but it gets confusing when you want target or send an event to a specific user as there is no clear way to exchange user data with the server. But in the video tutorial below; we have addressed the issues of sending global events as well as targeting specific users.

In the video tutorial below, we are going to build and deploy a realtime twitter-like newsfeed using server-sent events(SSE) with react.js, node.js and mongodb from the scratch and deploy it on cpanel.

This tutorial is for beginners and advanced programmers who wish to learn to implement the following;

  1. How to implement SSE in react js and node js application
  2. How to broadcast data to all users using server-sent events
  3. How to send data to a specific or single user using server-sent events
  4. How to implement LIKE button
  5. API(Application Programming Interface)
  6. React Hooks(useState, useContext, useReducer)
  7. Hosting(Deployment) on cpanel

Summary

Realtime data streaming has become a necessity in a standard modern application as this keeps your user notified of all the activities within your application. In this article, we discussed various techniques of client server communication and the need to go with server-sent events. Server-sent events(SSE) is a server push technology that enables a client to receive live stream updates from the server via a HTTP connection. It is lightweight and supported by most modern browsers and as a result, it's well suited for real-time automatic data stream from the server

Video Tutorial

If you want to watch and learn an in-depth tutorial on how to implement server-sent events(SSEs) with react js and node js, here is a video for you.

Please don't forget to like, comment, subscribe to my youtube channel and share the video with your friends.