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.