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:

AWS GenAI LIVE image

How is generative AI increasing efficiency?

Join AWS GenAI LIVE! to find out how gen AI is reshaping productivity, streamlining processes, and driving innovation.

Learn more

Top comments (0)

Redis image

Short-term memory for faster
AI agents

AI agents struggle with latency and context switching. Redis fixes it with a fast, in-memory layer for short-term context—plus native support for vectors and semi-structured data to keep real-time workflows on track.

Start building