Sling Academy
Home/Node.js/How to Use WebSockets for Real-Time Communication in Node.js

How to Use WebSockets for Real-Time Communication in Node.js

Last updated: December 29, 2023

Introduction

The WebSocket protocol is a distinctive feature on the web, enabling bidirectional communication between a client and a server. This tutorial will guide you through the implementation of WebSockets in Node.js for real-time communication, which is essential for applications like chat apps, live notifications, and online gaming. We’ll explore the basics, then move on to more advanced topics, such as broadcasting and error handling. Let’s dive in!

Setting Up Your Project

// Initialize a new Node.js project
npm init -y

// Install the 'ws' library
npm install ws

Basic WebSocket Server

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('Welcome to the WebSocket server!');
});

This code snippet sets up a basic WebSocket server on port 8080. When a client connects, it sends a welcome message to them, and any incoming message from the client is logged to the console.

Client-side WebSocket Connection

const serverUrl = 'ws://localhost:8080';
const connection = new WebSocket(serverUrl);

connection.onopen = () => {
  console.log('Connected to the server');
  connection.send('Hello, server!');
};

connection.onmessage = (event) => {
  console.log('Message from server ', event.data);
};

In the browser, you can create a new WebSocket instance pointing to the server’s URL. Once the connection is open, you can send messages to the server and set up a listener for messages coming from the server.

Broadcasting Messages

To enable broadcasting, each time a message is received from a client, the server needs to send this message to all connected clients:

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    wss.clients.forEach(function each(client) {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });
});

Handling Errors and Disconnections

It’s important to robustly handle errors and disconnections in your WebSocket applications. The following example demonstrates this:

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('message', /* handle messages as above */);

  ws.on('close', function close() {
    console.log('Client disconnected');
  });

  ws.on('error', function error(err) {
    console.error('WebSocket error', err);
  });
});

Securing Your WebSocket Connection

Real-world applications need to ensure security. Thus, using ‘wss://’ protocol with SSL/TLS encryption is a must when deploying on the web:

const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');

const server = https.createServer({
  cert: fs.readFileSync('path_to_cert.pem'),
  key: fs.readFileSync('path_to_key.pem')
});
const wss = new WebSocket.Server({ server });
// ... rest of the server code still applies

server.listen(8080);

We couple the WebSocket server with a native https server, where we pass our generating SSL certificates to secure the connection comprehensively.

What’s Next?

Scaling WebSocket Servers

For handling a large number of concurrent connections, you’ll want to scale out your WebSocket application. This can be accomplished via clustering in Node.js, or by leveraging a publish-subscribe pattern with solutions like Redis when expanded to multiple servers.

Testing WebSockets

Developing real-time applications requires thorough testing. Tools like Jest for unit testing or WebSocket testing libraries such as ‘ws’ can be used to simulate and test WebSocket interactions to ensure robustness and reliability of your application.

Conclusion

In this tutorial, we’ve gone through the basics of setting up WebSockets in Node.js, from establishing a basic server-client connection to handling broadcasting, errors, and ensuring security through SSL. Following these practices, you can roll out real-time features in your Web applications in Node.js environment both securely and efficiently.

Next Article: How to Send Email in Node.js (3 Approaches)

Previous Article: How to Write C/C++ Addons for Node.js

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