Create your first WebSockets-based application in NestJS
Duc Le
Posted on February 3, 2023
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
Then we will create a Gateway called MessageGateway
export class MessageGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
}
Don’t forget to add it to our providers in MessageModule
@Module({
imports: [TypeOrmModule.forFeature([Message])],
controllers: [MessagesController],
providers: [MessagesService, MessageGateway],
})
export class MessagesModule {}
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}`);
}
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);
}
With this piece of code, we will use SubscribeMessage
decorate 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
Next we will create a socket with it
import io from "socket.io-client";
const socket = io("http://localhost:3000");
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("");
}
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:
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
Posted on February 3, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.