DEV Community

Cover image for Realtime data streaming using server-sent events(SSE) with react.js and node.js
Peter Kelvin Torver
Peter Kelvin Torver

Posted on • Edited on • Originally published at codesermon.com

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

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.

You can also read

Stream Processing Paradigm: Enabling Continuous Data Analysis and Transformation

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.

You can also read

Stream Processing Paradigm: Enabling Continuous Data Analysis and Transformation

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)
}

Enter fullscreen mode Exit fullscreen mode

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})
}

Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode
source.addEventListener('open', function(e) {
  // successful connection.
}, false);
Enter fullscreen mode Exit fullscreen mode
source.addEventListener('error', function(e) {
  // error occurred
}, false);
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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

Resources & Demo

Get the code on github

Demo test, check it out here

You can also read

Stream Processing Paradigm: Enabling Continuous Data Analysis and Transformation

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.

Top comments (20)

Collapse
 
caschbre profile image
Craig Aschbrenner

Great article!

A couple of questions regarding SSEs...

Have you come across issues with the maximum number of connections (using http/1) as noted here? Or do you ensure http/2 is used?

Have you come across any limitations on the server for keeping connections open? I haven't been able to find much information on how many connections a server can keep open. I realize that's based on server hardware, number of instances, number of concurrent users, etc... but I've been trying to find a baseline number to compare.

Collapse
 
torver213 profile image
Peter Kelvin Torver

Thank you very much for asking this question. The max number(6) of connections indicated over there is per browser per domain. For instance with Google Chrome you can open 6 max number of connections to example.com and with ms edge you can still open another max connection of 6 to the same domain.
To answer your question;

  1. The number of connections a server can handle is limitless and depending on the capacity of your hardware just like you stated.
  2. What's indicated above is not possible in real life application because you can't just create 6 accounts on applications like twitter and login in this browser.
  3. Using HTTP/1 is the one with such limit but using HTTP/2 should increase it upto 100 max connections per browser per domain.
  4. The max number of connections indicated above is per browser per domain and not what your server can handle.

If you find anything worth sharing, please don't forget to share it with us. Thank you

Collapse
 
ana1vergara profile image
Ana Maria Vergara Posada

Hello,
The number of connections that the server support also depends on what web server you are using, for example, if you are using Apache, this formula gives you the number according to the hardware of your server:

(Total Memory – Critical Services Memory) / Size Per Apache process

It gives you the limit recommended for the Apache configuration, so your server will be optimized.

Collapse
 
tonystrawberry profile image
Tony Duong

Thank you! 😊

Collapse
 
waseyhasankhan profile image
waseyhasankhan

👍

Collapse
 
the-arcade-01 profile image
Aashish Koshti

Great post with clear and easy explanation 👌

Collapse
 
torver213 profile image
Peter Kelvin Torver

My pleasure

Collapse
 
codexpath2 profile image
Emmanuel Jacob

keep up man. great content

Collapse
 
torver213 profile image
Peter Kelvin Torver

My pleasure

Collapse
 
janpauldahlke profile image
jan paul

awesome article. I Just yesterday coded somehing very similar by chance, since my boss need to display streamed data in "real-time-charts".

Collapse
 
torver213 profile image
Peter Kelvin Torver

Wow that's great. Which tech stacks did u use?

Collapse
 
jreegene profile image
Jeremiah

Great article

Collapse
 
torver213 profile image
Peter Kelvin Torver

Thank you, Jeremiah

Collapse
 
doroszenko profile image
Andrzej

Thanks!

Collapse
 
torver213 profile image
Peter Kelvin Torver

Welcome

Collapse
 
copenju profile image
copenju

The Reveal Music was here ,thanks for this tutorial man keep up the good work

Collapse
 
torver213 profile image
Peter Kelvin Torver

You are welcome. Glad you found it helpful

Collapse
 
bastoker profile image
Bas 강남스타일 럭스

I think npmjs.com/package/@microsoft/fetch... deserves a mention here as well :-)