DEV Community

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

Posted on

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:

Top comments (0)