How to Use WebSockets in NestJS for Real-Time Communication

Updated: December 31, 2023 By: Guest Contributor Post a comment

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.