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

How to Use WebSockets in NestJS for Real-Time Communication

Last updated: December 31, 2023

Introduction

Real-time functionality is becoming crucial in modern web applications. NestJS, a progressive Node.js framework, provides an efficient way to establish real-time communication via WebSockets, allowing developers to implement live chat, notifications, and more.

Setting Up Your NestJS Project

Before diving into WebSockets, set up a new NestJS project if you haven’t already. Use the Nest CLI with the following command:

nest new real-time-app

Navigate to your project directory before proceeding to the next steps:

cd real-time-app

Installing WebSocket Dependencies

To get started with WebSockets in NestJS, you need to install @nestjs/websockets and socket.io. Run the following command:

npm install @nestjs/websockets @nestjs/platform-socket.io socket.io

Creating a Basic WebSocket Gateway

Now, let’s create a WebSocket gateway, which is a specific type of provider that Nest can instantiate and manage:

nest g gateway events

This command scaffolds a EventsGateway class. Go ahead and open the newly created file:

src/events/events.gateway.ts

Add basic event handlers to get the WebSocket communication started:

import { SubscribeMessage, WebSocketGateway, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';

@WebSocketGateway()
export class EventsGateway implements OnGatewayConnection, OnGatewayDisconnect {
  handleConnection(client: any, ...args: any[]) {
    console.log('Client connected:', client.id);
  }

  handleDisconnect(client: any) {
    console.log('Client disconnected:', client.id);
  }

  @SubscribeMessage('msgToServer')
  handleMessage(client: any, payload: string): string {
    return 'Message received: ' + payload;
  }
}

Note: msgToServer is the event’s name which the server listens for, and the handleMessage is the method that processes received messages.

Integrating WebSockets with Controller

WebSockets are usually used in conjunction with standard HTTP requests. To demonstrate how they can work together, let’s create a controller:

nest g controller events

Open the controller file and set up a route:

import { Controller, Post, Body } from '@nestjs/common';
import { EventsGateway } from './events.gateway';

@Controller('events')
export class EventsController {
  constructor(private eventsGateway: EventsGateway) {}

  @Post('message')
  sendMessage(@Body() data: { message: string }) {
    this.eventsGateway.server.emit('msgToClient', data.message);
  }
}

Advanced Usage: Rooms and Namespaces

For applications that need channeling or particular client groups, such as chat rooms, you can use rooms:

@SubscribeMessage('joinRoom')
handleJoinRoom(client: any, room: string) {
  client.join(room);
}

@SubscribeMessage('leaveRoom')
handleLeaveRoom(client: any, room: string) {
  client.leave(room);
}

@SubscribeMessage('msgToRoom')
handleMessageToRoom(client: any, { room, message }: { room: string; message: string; }) {
  this.server.to(room).emit('msgFromRoom', message);
}

NestJS also supports socket.io namespaces which allow for segmenting your application’s communication into logical partitions:

@WebSocketGateway({ namespace: 'chat' })
export class ChatGateway {
  // Gateway methods ...
}

Testing WebSocket Communication

To test your WebSocket implementation, consider using a client tool like socket.io-client or a browser library. Here’s an example script:

const io = require('socket.io-client');
let socket = io('http://localhost:3000');

socket.on('connect', () => {
  console.log('Connected to server');
  socket.emit('msgToServer', 'Hello NestJS');
});

socket.on('msgFromServer', (message) => {
  console.log('Message from server:', message);
});

Conclusion

Implementing WebSockets in NestJS taps into the real-time communication potential of your application, enabling features like real-time chat, live notifications, and interactive gaming experiences. The adaptable architecture of NestJS makes it suitable for handling WebSocket protocols and allows scaling as your application grows.

Next Article: How to Perform Unit Testing in NestJS Applications

Previous Article: How to Handle Authentication and Authorization in NestJS

Series: Nest.js Tutorials: From Basics to Advanced

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