The Mavenist

How to create a websocket gateway using Nest.js

2023-09-21


WebSockets are a communication protocol that enables bidirectional, real-time communication between a client and a server over a single, long-lived connection. Unlike traditional HTTP requests, which are request-response based, WebSockets provide a two-way (full-duplex), persistent connection that allows data to be sent and received at any time without the overhead of establishing a new connection for each exchange.



Advantages of using WebSocket connenctions are as follows:


  1. Real-time Communication - (Chat applications)
  2. Efficiency
  3. Full Duplex
  4. Low Latency
  5. Cross-Origin Communication
  6. Security

Overall, WebSockets are a powerful tool for building interactive, real-time web applications and have become an essential technology for modern web development.



To use WebSockets, you typically need both a client-side implementation (usually JavaScript in a web browser) and a server-side implementation. For the purposes of this tutorial we will be using Postman to test our websocket connection & on the server we will be using Nest.js.



Pre-requisites


  • A basic understanding of Nest.js & APIs
  • Postman for testing our socket connection

  • First of all we will need to make sure that we have the Nest.Js CLI installed. This will allow us scaffold and maintain our project locally.



    npm i -g @nestjs/cli


    Secondly we will need to install the relevant websocket packages from NPM:



    npm i --save @nestjs/websockets @nestjs/platform-socket.io


    Our folder structure will look like this:




    Below is a simple boilerplate to get us started.



    Websocket.ts


    1import { OnModuleInit } from '@nestjs/common';
    2import {
    3  MessageBody,
    4  SubscribeMessage,
    5  WebSocketGateway,
    6  WebSocketServer,
    7} from '@nestjs/websockets';
    8import { Server } from 'socket.io';
    9
    10@WebSocketGateway({
    11  cors: {
    12    origin: '*',
    13  },
    14})
    15export class Websocket implements OnModuleInit {
    16  constructor() {}
    17  @WebSocketServer()
    18  server: Server;
    19
    20  @SubscribeMessage('newMessage')
    21  onNewMessage(@MessageBody() body: any) {
    22    this.server.emit('onMessage', {
    23      msg: 'New Message',
    24      content: body,
    25    });
    26  }
    27}
    28

    Let's run through what is going on:



    First we begin by importing the OnModuleInit module from @nestjs/common - This is an interface that allows a class to define a lifecycle hook when a module is initialized.



    Next we import decorators MessageBody, SubscribeMessage, WebSocketGateway, WebSocketServer from '@nestjs/websockets'



    The @WebSocketServer() decorator is applied to the server property, which is of type Server (imported from 'socket.io'). This decorator is used to inject the WebSocket server instance into the class.



    The @SubscribeMessage('newMessage') decorator is applied to the onNewMessage method. This decorator indicates that this method should be called when a WebSocket client sends a message with the name 'newMessage'.



    The onNewMessage method takes a parameter annotated with @MessageBody(). This decorator is used to extract the message body from the incoming WebSocket message. Inside the method, it emits a new WebSocket message to all connected clients using this.server.emit(). The emitted message has the name 'onMessage' and includes a payload with the message 'New Message' and the content of the incoming message body.



    In summary, this code defines a WebSocket gateway using NestJS that listens for WebSocket messages with the name 'newMessage'. When such a message is received, it emits a 'onMessage' event to all connected WebSocket clients with a payload that includes 'New Message' and the content of the incoming message. This code provides a basic foundation for real-time communication using WebSockets in a NestJS application.



    Simulating a websocket connection using Postman


    Firstly we'll need to open Postman and create a new connection. As shown above you will need to select Socket.io



    1
    2import { NestFactory } from '@nestjs/core';
    3import { AppModule } from './app.module';
    4
    5async function bootstrap() {
    6  const app = await NestFactory.create(AppModule);
    7  await app.listen(5000);
    8}
    9bootstrap();
    10
    11

    Our application will be running on Port 5000 so lets start our development server using our start script below


    npm run start:dev



    As highlighted with the green arrow above we'll click on the connect button which will establish a connection with the server




    we will also add an onMessage event listener. This will subscribe to any events with this name and log them out.




    from client 1 we will then write "Hello world1!" & give it the event name "newMessage" which we added to the "@SubscribeMessage('newMessage')" decorator in our websocket.ts file.




    Once we send the message and move to client 2 tab we should see the message that was sent from client 1. And thats it! By following these steps you should be able to create a websocket connection using NestJs and Socket.io!