DEV Community

Cover image for Real-time Data Updates with Server-Sent Events (SSE) in Node.js
Franklin Thaker
Franklin Thaker

Posted on

3

Real-time Data Updates with Server-Sent Events (SSE) in Node.js

In this blog post, we'll explore how to use Server-Sent Events (SSE) to push real-time data from a server to clients. We'll create a simple example using Node.js and Express to demonstrate how SSE works.

What are Server-Sent Events (SSE)?

Server-Sent Events (SSE) allow servers to push updates to the client over a single, long-lived HTTP connection. Unlike WebSockets, SSE is a unidirectional protocol where updates flow from server to client. This makes SSE ideal for live data feeds like news updates, stock prices, or notifications.

Creating the Server

// app.js
const express = require("express");
const app = express();
const { v4 } = require("uuid");
let clients = [];

app.use(express.json());
app.use(express.static("./public"));

function sendDataToAllClients() {
  const value_to_send_to_all_clients = Math.floor(Math.random() * 1000) + 1;
  clients.forEach((client) =>
    client.response.write("data: " + value_to_send_to_all_clients + "\n\n")
  );
}

app.get("/subscribe", async (req, res) => {
  const clients_id = v4();
  const headers = {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    Connection: "keep-alive",
  };
  res.writeHead(200, headers);
  clients.push({ id: clients_id, response: res });

  // Close the connection when the client disconnects
  req.on("close", () => {
    clients = clients.filter((c) => c.id !== clients_id);
    console.log(`${clients_id} Connection closed`);
    res.end("OK");
  });
});

app.get("/data", (req, res) => {
  sendDataToAllClients();
  res.send("Data sent to all subscribed clients.");
});

app.listen(80, () => {
  console.log("Server is running on port 80");
});

Enter fullscreen mode Exit fullscreen mode

Code Explanation

  • Express Setup: We create an Express app and set up JSON parsing and static file serving.
  • Client Management: We maintain a list of connected clients.
  • SSE Headers: In the /subscribe endpoint, we set the necessary headers to establish an SSE connection.
  • Send Data: The sendDataToAllClients function sends random data to all subscribed clients.
  • Subscribe Endpoint: Clients connect to this endpoint to receive real-time updates.
  • Data Endpoint: This endpoint triggers the sendDataToAllClients function to send data.

Creating the Client

Next, let's create a simple HTML page to subscribe to the server and display the real-time data.

<!-- index.html  -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>SSE - Example (Server-Sent-Events)</title>
</head>
<body>
  <div id="data"></div>
</body>
</html>

<script>
  const subscription = new EventSource("/subscribe");

  // Default events
  subscription.addEventListener("open", () => {
    console.log("Connection opened");
  });

  subscription.addEventListener("error", () => {
    console.error("Subscription err'd");
    subscription.close();
  });

  subscription.addEventListener("message", (event) => {
    console.log("Receive message", event);
    document.getElementById("data").innerHTML += `${event.data}<br>`;
  });
</script>

Enter fullscreen mode Exit fullscreen mode

Code Explanation

  • EventSource: We create a new EventSource object to subscribe to the /subscribe endpoint.
  • Event Listeners: We set up listeners for open, error, and message events.
  • Display Data: When a message is received, we append the data to a div.

Running the Example

  1. Start the server:
    node app.js

  2. Open your browser and navigate to http://localhost/subscribe. [Don't close it]

  3. Now, open another tab & navigate to http://localhost/data and you should see random data prints onto the screen in other tab.

  4. You can subscribe to multiple clients/tabs as you want & you can simply navigate to http://localhost/data & you would see the same data emits to all the subscribed clients.

Conclusion

In this post, we've seen how to use Server-Sent Events (SSE) to push real-time updates from a server to connected clients using Node.js and Express. SSE is a simple yet powerful way to add real-time capabilities to your web applications without the complexity of WebSockets.

Warning⚠️:

When not used over HTTP/2, SSE suffers from a limitation to the maximum number of open connections, which can be especially painful when opening multiple tabs, as the limit is per browser and is set to a very low number (6). The issue has been marked as "Won't fix" in Chrome and Firefox. This limit is per browser + domain, which means that you can open 6 SSE connections across all of the tabs to www.example1.com and another 6 SSE connections to www.example2.com (per Stackoverflow). When using HTTP/2, the maximum number of simultaneous HTTP streams is negotiated between the server and the client (defaults to 100).

Happy coding!

Resources:

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay