Create your first WebSockets-based application in NestJS

leduc1901

Duc Le

Posted on February 3, 2023

Create your first WebSockets-based application in NestJS

Introduction

What are Websockets

Websockets is a communication protocol which provides full-duplex communication channels over a single TCP connection established between a web browser and a web server. This allows the server to sent to the browser without being called by the client. There are many usages of Websockets, like chat app, or account balance,… Where everything needs to be update in real time

Websockets in NestJS

According to NestJS, a gateway is simply a class annotated with @WebSocketGateway() decorator. Technically, gateways are platform-agnostic which makes them compatible with any WebSockets library once an adapter is created.

Before we dive in writing the application, I assume you already know how to create a NestJS application with TypeORM implemented, if not, you can check out my tutorial right here

Set up

We are going to build a simple send and receive message app

First, we need to install some dependencies

yarn add socket.io @nestjs/websockets @nestjs/platform-socket.io
Enter fullscreen mode Exit fullscreen mode

Then we will create a Gateway called MessageGateway

export class MessageGateway
  implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{

}
Enter fullscreen mode Exit fullscreen mode

Don’t forget to add it to our providers in MessageModule

@Module({
  imports: [TypeOrmModule.forFeature([Message])],
  controllers: [MessagesController],
  providers: [MessagesService, MessageGateway],
})
export class MessagesModule {}
Enter fullscreen mode Exit fullscreen mode

Build the Server

Right now the IDE will tell you that you need to have some methods called afterInit handleDisconnect handleConnection in MessageGateway

Because this is just a simple app, and we don’t actually need to do anything in these methods, we will simply log the data out

  private logger: Logger = new Logger('MessageGateway');

  @WebSocketServer() wss: Server;

  afterInit(server: Server) {
    this.logger.log('Initialized');
  }

  handleDisconnect(client: Socket) {
    this.logger.log(`Client Disconnected: ${client.id}`);
  }

  handleConnection(client: Socket, ...args: any[]) {
    this.logger.log(`Client Connected: ${client.id}`);
  }
Enter fullscreen mode Exit fullscreen mode

With this, we will know when the Server started, which client is connected and disconnected

Handle events

We need 2 events in this app, first is the sendMessage event and the second is receiveMessage event

@SubscribeMessage('sendMessage')
  async handleSendMessage(client: Socket, payload: string): Promise<void> {
    const newMessage = await this.messagesService.createMessage(payload);
    this.wss.emit('receiveMessage', newMessage);
  }
Enter fullscreen mode Exit fullscreen mode

With this piece of code, we will use SubscribeMessagedecorate to subscribe to the sendMessage event. Whenever a sendMessage event occured, we will create a new message through messageService .

Then we emit this created message through receiveMessage event

Build the Client

To test the gateway, we need a client, I will use the most popular UI library out there to test it, React

We need to install socket.io since the server uses socket.io

yarn add socket.io-client
Enter fullscreen mode Exit fullscreen mode

Next we will create a socket with it

import io from "socket.io-client";
const socket = io("http://localhost:3000");
Enter fullscreen mode Exit fullscreen mode

Then we will implement the socket:

  useEffect(() => {
    socket.on("receiveMessage", (msg) => {
      receiveMessage(msg);
    });

    getInitialMessages();
  }, []);

  function getInitialMessages() {
    fetch("http://localhost:3000/messages")
      .then((res) => res.json())
      .then((data) => {
        setMessages(data);
      });
  }

  function receiveMessage(msg: Message) {
    const newMessages = [...messages, msg];
    setMessages(newMessages);
  }

  function sendMessage() {
    socket.emit("sendMessage", newMessage);
    setNewMessage("");
  }
Enter fullscreen mode Exit fullscreen mode

You can see that on first render, I will subscribe to the receiveMessage event, to listen if there is any new event and take action with receiveMessage method. Then I get the initial messages through the get api

On receiveMessage method, I append new message to the state.

Every time we need to send a new message, we will emit sendMessage event

This will be the result:

Image description

Conclusion

This is the most basic example on how to create your first websockets app. You will know how to send and receive messages through the gateway. If the article is not that clear to you, just check out the source code

Last Words

Although my content is free for everyone, but if you find this article helpful, you can buy me a coffee here

💖 💪 🙅 🚩
leduc1901
Duc Le

Posted on February 3, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related