Introduction & Project Setup
All right, welcome back to another NestJS websocket tutorial. In this tutorial, you're going to now learn how to use the socket.io client library to actually connect to our websocket server. So in the last video, we created a websocket server and we used Postman to test everything out. But what we're going to do is we're going to do an actual real implementation of consuming the actual websocket server from a backend, okay? And then in the next video, I'll show you how we can consume the websockets from the front end.
So right now I have this nest.js socket consumer project. I just generated it. There's nothing in this project right now. Let me open up Visual Studio Code. Okay, so there's nothing at all. It's just like the basic scaffold of the project. And what we're going to do is we're going to connect to the actual websocket server. So I'll show you how this is going to work. Okay?
Creating the Socket Module
So what we'll do is I'll do the same thing. I'll create a new folder and I'll call this socket, and then I'll create a new file called socket.module.ts. Okay? And essentially what we'll do in this module is we'll go ahead and just set up a connection to the actual websocket server.
Now, how do we actually do that? Well, it's actually pretty, pretty simple. What we want to do is we want to just make a connection to the websocket server using the socket.io client library. Okay? In the last video, what we did was we used the actual platform socket.io and that's for actually setting up the socket.io server. In this video, we're going to be using the socket.io client library to make the actual connection to the server. So this is going to be a little bit tricky, but I'll show you how it works. Okay?
Implementing the Socket Client Service
Um, so what we'll do is we'll create a module, and I'll call this SocketModule, and then we're going to go ahead and annotate this with module, and we will pass in a providers array, and we'll pass in the value for the providers array in just a second.
I'll go into the file and I'll call this socket.client.ts. I'll create a class called SocketClient, and then this will have to be a provider, so we're going to go ahead and use Injectable. And then what I'll do is I'll take this SocketClient and I'll just pass it here and we'll auto-import that into the provider's array like this. Okay, so we're taking the SocketClient instance, or not the instance but the import reference, and passing it as a value inside the array.
Installing Dependencies & Establishing the Connection
And what we're going to do is we're going to go ahead and connect to the socket. So first let's just go ahead and install the socket.io library. So, that's really, really simple, or the socket.io client library. So we'll type yarn add socket.io-client. Socket.io-client. Okay. And then what we'll do is we'll go ahead and actually create an instance of the socket.io connection, and it's actually really, really simple.
So what I'll do is first I will go ahead and import io from socket.io-client. Okay. And then what I'll do is I'll go ahead and do this. I'll just simply do public socketClient, and the type will be Socket. Oops, this Socket type is actually supposed to come from the socket.io-client library. So we'll import Socket, and I'll just leave it like that for now. So that'll be the type annotation right over here. Okay.
Now this doesn't do anything yet. What we'll do is inside the constructor, we'll go ahead and reference this.socketClient equals and then we'll call the io function and we'll just pass in the URL to our websocket server, which is localhost:3000, as in the last video, same exact thing. Okay. And what I'll do is—so this should actually make a connection to the websocket server.
Listening for the Connection Event
Okay, and so what I'll do next is I'll go ahead and simply just do this. I'll just simply do this., or actually let me do this. Let me implement OnModuleInit interface, and then we'll implement the onModuleInit method. And once the module has initially initialized, we should be able to have this socketClient instance be truthy. So we can listen to the connect event, which is basically means that when our client has connected, it's going to trigger this event.
So I'll just write a console log, say "Connected to Gateway". Okay. So, um, before we proceed, we need to obviously import the SocketModule inside app.module.ts. So to do that, SocketModule, and let's just start up our application and hopefully everything goes well.
Testing the Connection and Fixing Port Conflicts
We should be able to see, let's see. It says—oh okay, whoops. We are using the same address. So let me just fix this real quick because our other application is running on Port 3000, so we need to change it to Port 3001. The consumer is going to run on Port 3001. Okay, now you can see it says "Connected to Gateway". If we go to the other console, you're going to see that it says "Connected". Okay, watch this. If I restart the app, right, we're going to get another log over here that says "Connected". Alright, so you can clearly see that the connection is in fact working, which is great.
Consuming Events from the WebSocket Server
So let's go into our consumer project and let's actually consume those events that are being sent from the websocket server. Okay, so we have the consumer, which is going to consume those events, and then we have the emitter. I'll call the emitter. The emitter is going to emit the events, so that's the websocket gateway. Okay?
So what I'll do is I want to register an event. So it's going to be the same event that is going to be emitted. So the server emits the onMessage event, so we want to consume that event. Now how do we do that? Well we just need to go ahead and reference this.socketClient.on and then the name of the event, so onMessage like this. Okay, but I don't want to do it this way. So what I'll do instead is I'll just go ahead and create a private method called registerConsumerEvents. And then I'll just simply take this, I'll move it down here, and then whenever the module is initialized, I'll just simply just call this.registerConsumerEvents. Okay, so this way it'll register all the events once the socket.io client has been initialized, otherwise if you call it before it's been initialized, it's going to give you a null error.
Okay so what we'll do now is we'll just simply register all of our events down here. So this.socketClient.on('onMessage'). Okay? And then it's going to go ahead and take in a callback function, and that callback function will have a payload, and we'll type annotate it as any. And let's just go ahead and do this. Let's just console log the payload. Okay? And yeah, that's pretty much it.
Emitting Events and Tracing the Round-Trip Flow
So let's go ahead and console log the payload and let's see what happens whenever a message is, whenever the onMessage event is emitted from the socket server.
Um, what we'll do is this, let's go into the server over here. Okay, so we do need to trigger this newMessage event somehow. So typically that would be triggered, um, in an actual application, the client would actually send that message to the websocket server, okay, and then the websocket server would emit that event onMessage and that would be sent to all the other connections. Okay?
So here's what I'll do. I'll just go ahead and inside the consumer, I'll go ahead and do this. I will simply reference the socket client and I will call emit. So I will go ahead and from the consumer side, I'm going to emit the event to the websocket gateway. The websocket gateway will receive that event and it's going to fire the onMessage event. So we're going to basically trigger the newMessage event right over here. So watch this. So I'm going to emit this event and for the payload, I'll just say message and I want you to look at the logs and watch what happens.
So what we did—and I know everything happened really fast, but let me just walk you through this—the SocketClient class was instantiated, created the socket.io instance, that's the server... the socket.io client that will connect to the server. Uh, whenever the onModuleInit method was called, it called registerConsumerEvents. Right over here, we emitted the newMessage event, okay, and we passed in this JSON object. And so this message was sent to the websocket gateway, which is this project over here.
We subscribe to the newMessage event, so whenever clients want to send us events with the name of newMessage, this is the method that will handle that. Okay? Uh, whenever we receive the newMessage event, we're going to trigger an onMessage event. The onMessage event is going to send alongside a payload with two properties: message and the original message body that was sent from the consumer. So that's why in the console over here, you see it says New Message content and then that's the original data that we sent. So it's working.
Verifying Broadcast with a Second Client (Postman)
I'll additionally go into Postman and I'll show you how this is going to work. So I'm going to go ahead and connect to the, I guess I'll connect to the gateway, or let me just make sure I'm doing this right. Let me just comment this line out. Uh, so I guess what I'll do is I'll connect to the gateway, and I will send an onMessage event, I guess. And actually no, no, wait. I'll connect to the gateway and I'll trigger the newMessage event. Okay. Um, the newMessage event over here will then emit the onMessage event which the consumer project will emit, will, will receive. Okay.
So let's go into Postman, let's do this. We're going to connect to our websocket server. Okay, we're going to go ahead and connect. And then we'll trigger the newMessage event. I'll just say hi. Okay, now watch this in the console. You will see in just a second, before I do anything, you're going to see that in the console, let me just restart this real quick. Let me just console log this, I'll just say 'socket client'. Let me restart. Okay, so this is the consumer project. So watch this. Send. See what it happens? Console logged hi, right?
So I am sending events to... So pretend like, uh, pretend like this is another user that is chatting, right? I'm sending messages to the websocket gateway. The websocket gateway is going to receive that event and it's going to emit its own event to all the other clients. Okay, see how that works? So that is how I'm consuming the client from another backend server. And a lot of times you might need to do this to receive live data, and you might want to do something and then send it somewhere else.
Conclusion & Next Steps
So I figured I'd make a video showing you how to do this because it can be really useful. Um, but yeah, so in the next tutorial what I'll do is I'll show you how you can set this up, uh, by how you can set up a React project to connect to the actual websocket server. Because right now we're just connecting it from server side to server side. I'll show you how to do it from client side to the actual server side. So thank you so much for watching. Hopefully you all enjoyed this video and I'll see you all in the next one. Peace out.