Scalable Real-Time Chat Application

Anik Malik

0

Fullstack Engineer

Software Engineer

Web Developer

MongoDB

NestJS

Socket.io

Scalable Real-Time Chat Application with NestJS, MongoDB, Redis, and Docker

Introduction

Real-time messaging is integral to modern apps across sectors, enhancing engagement and usability. This project focused on creating a scalable, efficient real-time chat application using NestJS, MongoDB, Redis, WebSockets, Socket.io, and Docker. Through this project, I was able to deliver a highly functional chat platform that scales seamlessly while maintaining performance and reliability.

Project Overview

Key Features:
One-to-One Messaging: Allows private, secure conversations between users.
Group Chats: Multiple users can join rooms to collaborate and chat.
Real-Time Communication: Leveraging WebSockets and Socket.io for instant message delivery.
Data Storage: MongoDB stores all user, chat, and room data securely.
Enhanced Performance: Redis caching optimizes frequently accessed data for better scalability.
Containerization: Docker is used for deploying both the app and Redis in containers, simplifying scaling.
Tech Stack:
NestJS: A robust Node.js framework for scalable, server-side applications.
MongoDB: A NoSQL database designed for efficient data storage.
Redis: Key for caching, improving the performance of user data and room states.
Socket.io: Enables real-time communication through WebSockets.
Docker: Ensures an isolated, replicable environment for app deployment.

Project Setup

1. NestJS Setup
To start, I initialized a new NestJS project and created a ChatModule to organize the chat logic. This structure contained services for chat operations, WebSocket event handling, and REST API routing.
Code for Initial Setup:
npx @nestjs/cli new chat-app
Project Structure:
src/
├── chat/
│ ├── chat.module.ts
│ ├── chat.gateway.ts
│ ├── chat.service.ts
│ └── chat.controller.ts
└── app.module.ts

2. MongoDB and Schema Definitions
Using Mongoose, I set up schemas for ChatRoom and Message to handle chat data. Room types and participant management were configured with pre-validation hooks to enforce rules based on room types and requirements.
ChatRoom Schema:
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';

@Schema({ timestamps: true })
export class ChatRoom extends Document {
@Prop() name: string;
@Prop({ required: true, enum: RoomType }) type: RoomType;
@Prop({ required: true, default: true }) status: boolean;
// Further participant, admin, and image properties...
}
export const ChatRoomSchema = SchemaFactory.createForClass(ChatRoom);
3. WebSocket and Socket.io Integration
Using Socket.io with NestJS WebSocketGateway, I managed real-time messaging through WebSocket events like message broadcasting within rooms and handling client connections/disconnections.
Sample WebSocket Code:
@WebSocketGateway({ cors: true })
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server: Server;

handleConnection(client: Socket) { console.log('User connected:', client.id); }
handleDisconnect(client: Socket) { console.log('User disconnected:', client.id); }

@SubscribeMessage('message')
handleMessage(client: Socket, payload: any) {
this.server.to(payload.room).emit('message', payload);
}
}

4. Redis for Caching
Redis improves performance by caching session data, room states, and frequently accessed data. This setup reduces MongoDB load, speeding up the app.
docker pull redis
npm install redis @nestjs/redis
Redis Configuration in ChatModule:
providers: [
{ provide: 'REDIS_CLIENT', useFactory: () => new Redis({ host: process.env.REDIS_HOST, port: +process.env.REDIS_PORT }) },
];
5. Docker Setup
Docker Compose was used to containerize the app and Redis, facilitating local development and production consistency.
Docker Compose Configuration:
version: '3'
services:
app:
build: .
ports:
- '3000:3000'
depends_on:
- redis
redis:
image: 'redis:latest'
ports:
- '6379:6379'

Challenges Faced

WebSocket Reconnection: Ensuring that rooms remain synchronized after users reconnect.
Redis in Docker: Overcoming initial Redis connection issues by updating host configurations.
Performance Optimization: Using Redis caching to manage high-frequency data access, reducing MongoDB load.

Lessons Learned

This project deepened my understanding of managing WebSocket connections, scaling with Redis, and containerization with Docker. The integration of Socket.io and NestJS allowed for seamless real-time communication, while Redis proved invaluable for enhancing performance and scalability.

Conclusion

This real-time chat application showcases a scalable architecture for instant communication, optimized through Redis caching and containerized with Docker. Future improvements could involve user authentication, media sharing, and fault-tolerant Redis clusters.
Like this project
0

Posted Nov 3, 2024

This project involved building a real-time chat application that is efficient, scalable, and capable of supporting one-to-one and group messaging with features

Likes

0

Views

1

Tags

Fullstack Engineer

Software Engineer

Web Developer

MongoDB

NestJS

Socket.io

Assessment app for students and mentors
Assessment app for students and mentors
Flight Travel site
Flight Travel site