Going Beyond That Simple Chat App Using socket.io

When people talk, listen completely. ~ Ernst Hemingway

Avinash Jaiswal
The Startup
6 min readJul 8, 2020

--

If we talk about communication over the internet there are many protocols (rules) that your messages can follow. HTTP(S), FTP, SSH, etc are all types of message communication protocols that our applications can use. The internet has an abundance of resources. Managing them over the network of computers is achieved using these message emitting and listening services. There is no example better than the internet if one talks about process communications.

Sockets are just another protocol for sending messages over the network. The reason sockets are so powerful, and therefore useful messaging construct is because-:

  1. They are light on bandwidth. Don't worry about your data usage once the connection is established.
  2. Fast to establish connections across system ports as compared to other protocols.
  3. Persistence of connection is provided. So once connected you tend to stay connected unless you close the socket manually or programmatically.

Sockets have lately been one of my favorite technology to work upon. I got to use them extensively while solving the concurrency management issue of graffitee.ml. I am quite a fan of this particular socket library called socket.io that promises to help you build amazing applications in less than 200 lines of code. One just needs an idea that works well with sockets. Rest can be left upon socket.io and its server and client methods.

So, what type of scenario calls for using sockets!? In my experience whenever there has been a need to communicate between the frontend and backend and to account for the number of users that are presently connected to the backend, I have used sockets. Be it for creating public bulletin boards, handling client-side concurrency issues, or creating private rooms for clients to communicate, all use sockets very effectively.

Sockets have tremendous use cases if implemented but we all need to start small. Here we are trying to go beyond the basic chat app you build when you go through the “Get started” section of socket.io and aspire to add functionalities like

  1. in-room messaging
  2. typing notifications
  3. generating random names for users connecting to our application, and
  4. track all the online users.

A prerequisite to this would be that you already have the basic chat app implemented and a machine that has NodeJs up and running.

If you give your present code a second look, you might see that apart from the usual server and client-side logic we have two very important socket.io methods, each at the server and client ends which make the communication of messages possible. These are the emit and on methods.

Client-side~
io.emit('chat message',{msg});
Server-side~
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
io.emit('chat message', msg);
});
});

What you have as of now is a chat application where all your clients can connect and can broadcast messages that can be seen by everyone else. This type of application have a few use cases, but most of the time we are concerned with creating private spaces, or as socket.io calls them, rooms so that our users can have closed communications. So let's move onto creating rooms-:

Creating rooms-:

So for creating rooms we need two things. One a unique room ID and the other the join method provided by socket.io. For creating a unique ID you can either use a random number generator from the language or might also go over npm and use a module called UUID. It provides many pseudo-random number generator functions that can integrate seamlessly with your code.

As you start, you will be emitting an “ack” i.e an acknowledgment message from the client. This will notify the server of the presence of your client. You can then use your random string generated from UUID and provide it to the socket.join() method. Refer to the code below for an example.

Code to join a room

A socket is essentially an object, hence you can create your own properties on the fly. We will be needing a data structure to store all your sockets. This is a good utility when it comes to managing sockets and also to get the participant count in a room. I prefer to use an object for this. Refer to the code below for more insights.

Objects use to maintain sockets

You now have your sockets properly structured and maintained in a few “maintainer objects”. On this note, I should mention that this is not something that socket.io explicitly mentions or is one of the best practices prescribed by the library but instead it's just something that I like to do with my code. The socket.io API tends to change as the library evolves but these data stores are API independent as we are only dependent upon the basic emit, on, and join methods.

In the end, use the io.in() method to emit the message in the room of your choice so that all the participants of that room receives them.

io.in(room).emit(‘ackback’,{msg});

Typing notification-:

We now know that all the communication that happens between ports in socket.io is the result of “matching” emit and on methods. The namespace provided to these methods needs to be the same and then any communication is possible between them, be it media blobs or simple text strings.

Below is a client-side implementation of how would want to emit notifications when the user is typing. If you understand this bit, it will be easy enough for you to implement the corresponding server-side code.

Code to track user typing

Generating random names for users-:

Moving on, we have two very simple problems present before us. Given we have already done much of the heavy lifting by tracking our users and their activities, we should now be confident enough in implementing such additional attributes in our chat system.

For generating random names for your users you can use many unique name generators that are present over npm. Their integration into the code is also fairly straight forward. You just need to assign every socket a name property and then use it the way you want. I guess I can save myself from adding another picture for this segment ;-)

Tracking all the online users-:

If you see the figure that was provided for creating rooms you might notice there is an object called “numClients”. This is specially used to track the number of users in a particular room. Depending on the use case, you can as well return the number that is maintained in this object from your server and that would be the present number of clients that are connected to your room. Nothing serious, all simple code abstractions.

The more you play with sockets, the more insights you will get on how to solve your communication problems in a decoupled application. You just need to be mindful of the basics of on and emit events. The rest will just follow in place. Do use sockets and socket.io in creating the next amazing thing you are planning to create. Once an interest is developed do checkout the lower level web sockets API on top of which socket.io is essentially implemented. You will find a lot of hidden treasures and will have so much to learn about networks and their implementation. Till then, The sky is the limit!!

--

--