Overview

Add real-time capabilities using WebSocket gateways. Perfect for chat, live updates, and collaborative features.

Features

  • Socket.io integration
  • Room management
  • Broadcast functionality
  • Connection lifecycle hooks

Installation

npx hanma add nest-websocket --framework nest

Dependencies

@nestjs/websockets, @nestjs/platform-socket.io, socket.io

Code

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

interface AuthenticatedSocket extends Socket {
  userId?: string;
}

@WebSocketGateway({
  cors: {
    origin: process.env.CORS_ORIGIN?.split(",") || "*",
    credentials: true,
  },
  namespace: "/ws",
})
export class WebsocketGateway
  implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
  @WebSocketServer()
  server: Server;

  private readonly logger = new Logger(WebsocketGateway.name);
  private connectedClients = new Map<string, AuthenticatedSocket>();

  afterInit(server: Server) {
    this.logger.log("WebSocket Gateway initialized");
  }

  handleConnection(client: AuthenticatedSocket) {
    const { sockets } = this.server.sockets;
    this.logger.log(`Client connected: ${client.id} (Total: ${sockets.size})`);
  }

  handleDisconnect(client: AuthenticatedSocket) {
    this.connectedClients.delete(client.id);
    this.logger.log(`Client disconnected: ${client.id}`);
  }

  @SubscribeMessage("ping")
  handlePing(@ConnectedSocket() client: Socket): { event: string; data: string } {
    return { event: "pong", data: new Date().toISOString() };
  }

  @SubscribeMessage("joinRoom")
  handleJoinRoom(
    @ConnectedSocket() client: Socket,
    @MessageBody() room: string
  ): void {
    client.join(room);
    this.logger.log(`Client ${client.id} joined room: ${room}`);
    client.emit("roomJoined", { room });
  }

  @SubscribeMessage("leaveRoom")
  handleLeaveRoom(
    @ConnectedSocket() client: Socket,
    @MessageBody() room: string
  ): void {
    client.leave(room);
    this.logger.log(`Client ${client.id} left room: ${room}`);
    client.emit("roomLeft", { room });
  }

  @SubscribeMessage("message")
  handleMessage(
    @ConnectedSocket() client: Socket,
    @MessageBody() payload: { room?: string; message: string }
  ): void {
    if (payload.room) {
      this.server.to(payload.room).emit("message", {
        from: client.id,
        message: payload.message,
        timestamp: new Date().toISOString(),
      });
    } else {
      this.server.emit("message", {
        from: client.id,
        message: payload.message,
        timestamp: new Date().toISOString(),
      });
    }
  }

  // Utility methods for broadcasting
  broadcastToAll(event: string, data: unknown): void {
    this.server.emit(event, data);
  }

  broadcastToRoom(room: string, event: string, data: unknown): void {
    this.server.to(room).emit(event, data);
  }

  sendToClient(clientId: string, event: string, data: unknown): void {
    this.server.to(clientId).emit(event, data);
  }
}

Usage

// Add to module providers
@Module({
  providers: [WebsocketGateway],
})

Dependencies

Frequently Asked Questions

How do I install WebSocket Gateway?
Run the following command: npx hanma add nest-websocket --framework nest
What dependencies are required?
This snippet requires: @nestjs/websockets, @nestjs/platform-socket.io, socket.io. Make sure to install them before using the snippet.
How do I use this snippet?
Copy the code and paste it into your project. The snippet will be saved to src/gateways/websocket.gateway.ts.
Can I customize this snippet?
Yes! All snippets are copy-paste code that you own. Feel free to modify them to fit your needs.
Does this work with other frameworks?
This snippet is designed for the specific framework. Check the other framework pages for equivalent implementations.