How SSE Works[source]

Server-Sent Events (SSE) — A Comprehensive Guide

Ibraheem Hamshari
4 min readSep 24, 2024

Introduction

Server-Sent Events (SSE) is a powerful and efficient method for servers to push real-time updates to clients over HTTP. Unlike WebSockets, which facilitate two-way communication, SSE provides a one-way channel from the server to the client. This makes it a simpler, more efficient choice for use cases that only require server-to-client communication, such as sending notifications, updating stock prices, or delivering real-time messages in a chat system.

In this guide, we will provide a thorough understanding of SSE, covering how it works, its advantages, and a step-by-step practical implementation using Node.js.

Prerequisites

Before diving into the implementation, make sure you have the following:

  • Basic knowledge of Node.js
  • Understanding of the HTTP protocol and RESTful APIs

1. What Are Server-Sent Events (SSE)?

1.1 Overview of SSE

Server-Sent Events (SSE) is a technology that allows a server to push updates to a client over a long-lived HTTP connection. Once established, the client listens for updates, and the server sends data whenever it has new information. Unlike WebSockets, which allow for bidirectional communication, SSE is designed for one-way communication from the server to the client.

1.2 How SSE Works

The process of establishing an SSE connection involves the following steps:

  1. Client Request: The client sends an HTTP request to the server to open a connection.
  2. Server Response: The server responds with an HTTP header: Content-Type: text/event-stream. This header tells the client to expect a stream of events.
  3. Streaming Data: The server sends events to the client in a special format, keeping the connection open until either the server or the client decides to close it.

1.3 Key Features of SSE

  • One-way Communication: Data flows from server to client only.
  • Automatic Reconnection: The client automatically tries to reconnect if the connection is dropped.
  • Event IDs: The server can send event IDs to help the client keep track of which events it has already processed, ensuring it doesn’t miss any updates.
  • Custom Events: In addition to the standard message event, the server can send custom event types.

1.4 Advantages of SSE

  • Simplicity: SSE is simpler than WebSockets for cases where only server-to-client communication is needed.
  • Browser Support: Most modern browsers have built-in support for SSE through the EventSource API, making it easy to implement.
  • Works with HTTP: SSE uses standard HTTP/1.1 or HTTP/2 protocols, meaning no additional protocols or handshakes are necessary.

2. Implementing SSE in Node.js

Now, let’s implement SSE in a Node.js environment.

2.1 Setting Up the Project

To get started, create a new Node.js project and install the necessary dependencies.

mkdir sse-example
cd sse-example
npm init -y
npm install express

Next, create a server.js file to handle the server-side logic.

const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
res.send('Welcome to SSE Demo');
});
app.get('/events', (req, res) => {
// Set headers to enable SSE
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const sendEvent = (data) => {
res.write(`data: ${JSON.stringify(data)}\n\n`);
};
// Send an event every 3 seconds
const intervalId = setInterval(() => {
sendEvent({ message: 'Hello from the server!', timestamp: new Date().toISOString() });
}, 3000);
// Handle client disconnection
req.on('close', () => {
clearInterval(intervalId);
res.end();
});
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});

In this code:

  • We create an Express server with two routes: / for a welcome message and /events for sending SSE updates.
  • The /events route sets the appropriate headers to enable SSE (text/event-stream, Cache-Control, and Connection).
  • The server sends an event every 3 seconds, and when the client disconnects, the server clears the interval and closes the connection.

2.2 Client-Side Implementation

Now let’s create a simple client to receive and display the SSE events. Create an index.html file with the following code:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSE Demo</title>
</head>
<body>
<h1>Server-Sent Events Demo</h1>
<div id="events"></div>
<script>
const eventSource = new EventSource('/events');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
const eventsDiv = document.getElementById('events');
eventsDiv.innerHTML += `<p>${data.timestamp}: ${data.message}</p>`;
};
eventSource.onerror = (error) => {
console.error('Error receiving SSE', error);
};
</script>
</body>
</html>

In this example:

  • The EventSource API is used to open a connection to the /events endpoint on the server.
  • The onmessage event handler listens for incoming messages and appends them to the DOM.
  • If there is an error with the connection, the onerror event handler logs the error to the console.

2.3 Running the Example

To see the SSE in action:

  • Start your Node.js server:
node server.js
  • Open index.html in a browser and watch the real-time updates as they are pushed from the server to the client.

Conclusion

Server-Sent Events (SSE) is a great solution for use cases where a server needs to continuously push updates to a client without the complexity of bidirectional communication. With built-in support in modern browsers, SSE is simple to implement and highly effective for applications like notifications, live feeds, or real-time updates.

By following this guide, you now have a complete understanding of how SSE works and how to implement it in a Node.js project. Happy coding!

--

--

Ibraheem Hamshari
Ibraheem Hamshari

Written by Ibraheem Hamshari

Full-Stack Developer | Web Development, React, Node.js | Passionate about clean code and software architecture.

Responses (1)