Using Sockets for Chat Applications in NestJS

@rnab
3 min readJan 19, 2025

--

The rapid evolution in communication technology has exponentially increased the demand for real-time applications. Whether it’s a gaming platform, a collaborative tool, or a simple chat application, real-time communication is a game-changer. Among the various technologies available for implementing real-time communication, WebSockets stand out as one of the most efficient. In this article, we’ll delve into how to use WebSockets in NestJS to build a real-time chat application with TypeScript.

Introduction to NestJS

NestJS is a progressive Node.js framework that builds efficient, reliable, and scalable server-side applications. The framework is built with TypeScript and combines elements of Object-Oriented Programming (OOP), Functional Programming (FP), and Functional Reactive Programming (FRP).

NestJS leverages many tools, including WebSockets, to build real-time applications with minimal hassle. In this article, we will focus on how to integrate WebSockets into a NestJS application to build a real-time chat environment.

Setting Up the Environment

Before we dive into the coding part, let’s set up our NestJS application. Begin by installing the NestJS CLI if you haven’t done so already.

npm i -g @nestjs/cli

Create a new NestJS project named “chat-app”.

nest new chat-app

Navigate to the newly created project directory.

cd chat-app

Installing Dependencies

To enable WebSocket communication in our NestJS application, we’ll need to install the @nestjs/websockets and @nestjs/platform-socket.io packages.

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

Implementing the WebSocket Gateway

In NestJS, Gateways are the WebSocket equivalent of Controllers in a RESTful API. They allow us to define message handlers and event listeners.

Create a new gateway using the CLI.

nest generate gateway chat

This command will generate a file named chat.gateway.ts. Let's configure this file to handle chat messages.

import {
WebSocketGateway,
SubscribeMessage,
MessageBody,
ConnectedSocket,
WebSocketServer,
OnGatewayInit,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';

@WebSocketGateway()
export class ChatGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
@WebSocketServer() server: Server;

private connectedUsers: Set<string> = new Set();

afterInit(server: Server) {
console.log('WebSocket server initialized');
}

handleConnection(@ConnectedSocket() client: Socket) {
console.log(`Client connected: ${client.id}`);
}

handleDisconnect(@ConnectedSocket() client: Socket) {
console.log(`Client disconnected: ${client.id}`);
this.connectedUsers.delete(client.id);
this.server.emit('users', Array.from(this.connectedUsers));
}

@SubscribeMessage('message')
handleMessage(
@MessageBody() message: { sender: string; content: string },
@ConnectedSocket() client: Socket
) {
this.server.emit('message', message);
}

@SubscribeMessage('join')
handleJoin(
@MessageBody() username: string,
@ConnectedSocket() client: Socket
) {
this.connectedUsers.add(username);
this.server.emit('users', Array.from(this.connectedUsers));
}
}

In this code:

  • WebSocketGateway: Indicates that this class is a WebSocket gateway.
  • WebSocketServer(): Decorator to inject the WebSocket server instance.
  • @SubscribeMessage(): Decorator to listen for a specific event, such as ‘message’ or ‘join’.
  • OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect: Interfaces to handle gateway lifecycle events.

Creating the Chat Service

While a simple chat application can function solely with a gateway, it is a good practice to separate logic into services. This keeps your codebase scalable and maintainable.

Create a new service using the CLI.

nest generate service chat

Modify the chat.service.ts file to include basic chat logic (optional based on the features you need). For simplicity, we will keep it empty for now.

import { Injectable } from '@nestjs/common';

@Injectable()
export class ChatService {
// Future chat logic can go here
}

Modifying the Chat Module

The chat.module.ts file will be modified to include both the gateway and the service.

import { Module } from '@nestjs/common';
import { ChatGateway } from './chat.gateway';
import { ChatService } from './chat.service';

@Module({
providers: [ChatGateway, ChatService],
})
export class ChatModule {}

Running the Application

Ensure that your src/app.module.ts includes the ChatModule.

import { Module } from '@nestjs/common';
import { ChatModule } from './chat/chat.module';

@Module({
imports: [ChatModule],
controllers: [],
providers: [],
})
export class AppModule {}

Now, run the NestJS application.

npm run start

Your WebSocket server should be up and running, ready to handle connections and messaging.

Conclusion

Integrating WebSockets into a NestJS application for real-time chat functionality is straightforward and efficient. NestJS provides an organized and scalable way to handle WebSocket connections and messaging, making it an excellent choice for building real-time applications. By following the steps outlined above, you can create a robust chat application that leverages the power of WebSockets in NestJS with TypeScript.

--

--

@rnab
@rnab

Written by @rnab

Typescript, Devops, Kubernetes, AWS, AI/ML, Algo Trading

No responses yet