Sling Academy
Home/Node.js/How to Implement Server-Sent Events in Node.js for Real-Time Updates

How to Implement Server-Sent Events in Node.js for Real-Time Updates

Last updated: December 29, 2023

Server-Sent Events (SSE) is a web technology that enables servers to send updates to the client in real-time. It is a much simpler alternative to WebSockets and a suitable choice when the server needs to push updates to clients without a request, but the clients do not necessarily need to send messages to the server. This tutorial demonstrates how to implement SSE in a Node.js application.

Setting Up the Project

To get started, initiate a new Node.js project by running npm init in your terminal. Once you have your package.json file ready, install the ‘express’ library as our server framework using npm install express.

Creating the Server

Create a new file named server.js. Begin with setting up an Express server that can serve static files and that has a route prepared to handle SSE:

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

app.use(express.static('public'));

app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  //... more to follow
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); 

Implementing SSE

In the ‘/events’ route, you implement the actual SSE handling. Here is an essential configuration pattern:

app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.flushHeaders();

  // Sends a simple message at a set interval
  const interval = setInterval(() => {
    res.write(`data: ${new Date().toLocaleTimeString()}

`);
  }, 1000);

  req.on('close', () => {
    clearInterval(interval);
  });
}); 

Here, data is sent to the client every second with the current time. If the client disconnects, the event will stop sending the updates.

Client-Side Setup

You also need some client-side JavaScript to interact with the stream:

const eventSource = new EventSource('/events');
eventSource.onmessage = function(e) {
  console.log('Message:', e.data);
};
eventSource.onerror = function(e) {
  console.error('Error occurred', e);
}; 

Now, everything is set up for the server to stream data, and the client to receive updates in real time.

Complete Server Code Example

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

app.use(express.static('public'));

app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.flushHeaders();

  const interval = setInterval(() => {
    res.write(`data: ${new Date().toLocaleTimeString()}

`);
  }, 1000);

  req.on('close', () => {
    clearInterval(interval);
  });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); 

Conclusion

In this article, we walked through the steps to implement SSE in a Node.js application using Express. With SSE, you efficiently establish a one-way channel from the server to the client, allowing the server to send real-time updates while preserving the simplicity and lower complexity compared to WebSockets. Now you should have a solid foundational understanding of how Server-Sent Events can be used in your web applications.

Next Article: How to Build a GraphQL API with Node.js and Apollo Server

Previous Article: How to Use Child Processes in Node.js for CPU-Intensive Tasks

Series: Node.js Intermediate Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates