Integration with WebSockets
Environment Preparation
- Node.js: Install the latest stable version.
- NestJS: Initialize a project using npm or yarn.
Creating a NestJS Project
npm init nest new websocket-app
cd websocket-appInstalling WebSocket Dependencies
npm install @nestjs/websocketsConfiguring the WebSocket Module
Import the WebSocketModule in src/app.module.ts.
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { WebSocketModule } from '@nestjs/websockets';
@Module({
imports: [WebSocketModule.register({ namespace: 'chat' })],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Creating a WebSocket Service
Generate a new service to handle WebSocket connections.
nest generate websocket chatEdit src/chat/chat.gateway.ts:
import { WebSocketGateway, SubscribeMessage, MessageBody, ConnectedSocket, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
import { Socket } from 'socket.io-client';
@WebSocketGateway({ namespace: 'chat' })
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
constructor() {}
handleConnection(@ConnectedSocket() client: Socket) {
console.log('Client connected');
}
handleDisconnect(@ConnectedSocket() client: Socket) {
console.log('Client disconnected');
}
@SubscribeMessage('message')
handleMessage(@ConnectedSocket() client: Socket, @MessageBody() data: any): void {
this.server.to(client.id).emit('message', data);
}
}Connection Testing
Start the server:
npm run start:devTest the connection using a client library like socket.io-client:
const socket = io('http://localhost:3000/chat');
socket.on('connect', () => {
console.log('Connected to server');
socket.emit('message', { text: 'Hello from the client!' });
});
socket.on('message', (data) => {
console.log('Received message:', data.text);
});Gateways
Gateways are special classes in NestJS used to handle WebSocket connections. They enable bidirectional communication between the application and clients via the WebSocket protocol.
Definition:
- Create a new gateway class that extends
WebSocketGateway. - Use the
@WebSocketGateway()decorator to configure the gateway.
import { WebSocketGateway, SubscribeMessage, MessageBody, ConnectedSocket } from '@nestjs/websockets';
import { Socket } from 'socket.io-client';
@WebSocketGateway({ namespace: 'chat' })
export class ChatGateway {
@SubscribeMessage('message')
handleMessage(@ConnectedSocket() client: Socket, @MessageBody() data: any): void {
this.server.to(client.id).emit('message', data);
}
}Exception Filters
Exception filters are used to catch and handle exceptions in controllers. They can be registered globally or applied to specific controllers or routes.
Definition:
- Create a class that implements the
Catchdecorator. - Implement the
catchmethod to handle exceptions.
import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '@nestjs/common';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const status = exception.getStatus();
response.status(status).json({
statusCode: status,
message: exception.message,
error: 'Some error occurred',
});
}
}Pipes
Pipes are used to validate and transform incoming data. They run before the route handler processes the request.
Definition:
- Create a class that implements the
PipeTransforminterface. - Implement the
transformmethod to process data.
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
@Injectable()
export class ValidationPipe implements PipeTransform<any> {
transform(value: any, metadata: ArgumentMetadata) {
if (!value || typeof value !== 'object') {
throw new BadRequestException('Invalid data format');
}
return value;
}
}Guards
Guards protect routes or methods from unauthorized access. They run before the request reaches the controller.
Definition:
- Create a class that implements the
CanActivateinterface. - Implement the
canActivatemethod to determine if the request should proceed.
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext) {
// Get the request object
const request = context.switchToHttp().getRequest();
// Check if the user is authenticated
return request.isAuthenticated();
}
}Interceptors
Interceptors modify method calls entering and leaving controllers. They can run before the request reaches the controller or after the response is sent to the client.
Definition:
- Create a class that implements the
NestInterceptorinterface. - Implement the
interceptmethod to handle requests and responses.
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
const now = Date.now();
return next.handle().pipe(
map((data) => {
console.log(`After... ${Date.now() - now}ms`);
return data;
}),
);
}
}Adapters
Adapters are used to integrate external libraries or services into the NestJS framework. For example, a WebSocket adapter allows the use of different WebSocket libraries.
Definition:
- Create a class that implements the
WebSocketAdapterinterface. - Implement methods to handle connections, disconnections, and message events.
import { WebSocketAdapter } from '@nestjs/platform-socket.io';
import * as io from 'socket.io';
export class CustomWebSocketAdapter extends WebSocketAdapter {
createIOServer(port: number, options?: any): any {
return io(port, options);
}
}



