UI Development

Building Chat Application Using SocketIO

Introduction

Today we will be building a basic chat application to connect multiple users where they can interact with each other in real-time. We are going to use Socket.io, Express, and NodeJS to achieve it. Let’s have some brief knowledge of what these technologies are and how we are going to use this, to build our Chat-Application.

What’s Socket.IO?

As per given definition on website https://socket.io: Socket.IO is a library that enables real-timebidirectional and event-based communication between the browser and the server. Socket.io is not built from ground up it uses already established WebSocket technology. Now let’s understand what these keywords represent:

Library: It means it is a JavaScript library/framework which is built and maintained as a node module so we can easily add this to our project as a dependency to use it.

Real-time: Any communication between server and client where information/data is updated without refreshing the state of connection is happening in real-time.

WebSockets: Socket.io is built on engine.io which uses WebSockets internally. In WebSockets, a full duplex connection is made between the server and client.

How does it work?

A simple HTTP handshake takes place at the beginning of a Socket.IO connection. After initial handshake sockets can communicate with much less memory usage, which speeds up the client-server connection. After the handshake, the connection is bi-directional i.e. data can flow both ways without interruption.

Normally, communication between client and server occurs with multiple HTTP requests being made every time a piece of data is retrieved or needs to be updated, but this is not the case when using WebSockets. Since the connection is left open, any updates or changes are sent directly, and this leads to huge savings in both latency and performance. Another huge benefit of using Socket.io is that it comes with excellent cross-browser and device support, so you can expect the same speed and performance across all platforms, browsers, and connected devices, and this is because connections are initiated and maintained within the browser window.

Now, let’s build simple Chat Application, you must have node installed in your system if not got to this link and install it in your system.

A) INITIAL SETUP SOCKET.IO

  1. Create a repository for your project and then set up the project structure. It’s very simple to write the following commands on your terminal.
    1. Use mkdir along with the name of your project.
    2. Use cd move to that folder
    3. Initialize the project using command npm init which will create a package.json file which is required to manage your application dependencies and other things.
    4. Create a public folder in root repo for UI of the app create one index.html inside it.
    5. Create one server.js for creating server configuration and actions.
2. Let’s add the required dependencies for this project. We are adding express to create server, socket.io to handle dual-channel connection and path for working directory file paths.

Run this command in your repository

Now your updated package.json file should look like this after adding the dependencies.

package.json file

3. Now let’s go back to your app.js/server.js file open it in your IDE. Here require the respective modules needed express, path, etc. we would serve our application using node express HTTP server. Use io variable for further creating a socket connection. Also, we will be maintaining two arrays one for all the active socket connection and one for all the usernames. Let’s define a port number of choice for our server to serve the index file on.

Add this code to your server.js file

4. Now we will serve our index.html from our HTTP express server to this we would use express request handler ‘use()’ and serve our HTML file from the public folder. To run the server we will server.listen()passing the port number.

 

Add this code to listen on your server in server.js file

5. So now, we have the server running we will create our first socket connection. To do this we will use io variable defined above (point 3) With our setup in place, let’s create our first connection. We’ll do so by opening our app.js file and creating connections using our io variable declared above. We can use the on method provided to us by socket.io, and then specify an event known as connection. This connection string is part of the Socket.io library and does the job of opening connections between the client and the server. We’ve added a socket argument here that’s going to be used every time we want to send and receive messages. Let’s also add a log message letting us know a new connection has been made.

Created your first connection – server.js → code.

Now, let’s set up the connection to our client. So, we’ll open our index.html file, and it’s very easy to initiate the connection, also known as a handshake, between our client and server. All we need to do is set a variable for our socket and pass in our server location. And we do this inside of a script tag.

Here we have it, open command line in root directory of your project and run command node server.js then open the browser http://localhost:8000


B) SENDING AND RECEIVING MESSAGES

Sending and receiving messages in socket.io is based on publishers-subscriber pattern which you generally see in some of the other JavaScript frameworks. Essentially, we emit/publish events from one-side (either server/client) and receive on the other to do so we emit some event let’s say on client-side with some name ‘send-message’ along with respective ‘data/information’ now on the client-side(index.html)we must subscribe for the same event name that is going to occur so when whenever the event gets triggered the receiver/sub has the ability to intercept the event along with the data it is transferring.

Publisher does not need to know about the individual receiver it just needs to publish, and the registered subscriber can easily receive the message sent by the publisher create loosely coupled relation between them. Here will be sending JSON objects as data to one another for communication.

Let’s create some basic UI for our messages to show when we send or receive them open your index.html file and add the following code.

We are going to use PureJs to capture tags for event handling – link

Here we have created two different sections one would act as a simple login screen while the other after login where the user can send and receive messages. All the active user are shown in UI under the userForm area.

A user would have the ability to send a message from a message area which is just a text area on pressing of send we will emit an event ‘new-message’ any event name of your choice. We will subscribe this method in server.js emit the same event with the user-name attached to it so it will be fetched at UI end to render on-screen from whom it was sent along with data from the message. This will be rendered on any user screen who are part of this socket connection.

        
  • Event Listener and Emitting an event‘messageForm’ is an HTML form element, we are adding JS event-listener to it if the user sends a message, we then emit a socket-event name ‘message-from-client’, along with the JSON data value which contains text written by the user in message-box paired with a key name ‘message’. And truncating message box value to adding newer messages. link
  • Inside server.js we have our already existing function here we add a subscriber to event ‘message-from-client’ using socketio. So, whenever the server receives such an event, it executes a callback function wherein parameter you can pass the data/message. Inside here, we will emit ‘io.socket.emit’ which is meant for all IO connected clients with the details of a message received from one of the client and along with the username associated with that socket connection. link.

In a similar way, we will create will add a new look for the user to enter the chat by entering his desired username and enter the chat. We will again use the pub/sub pattern here.

userFormArea.addEventListener("submit", function(event) { 
  event.preventDefault();
  socket.emit("new-user", userName.value, function(data) {
    if (data) {
     userFormArea.style.display = "none"; 
     messageArea.style.display = "flex"; 
    }
  }); 
  userName.value = ""; 
});

An event is emitted from the index.html page. Here we are just sending the user details in our case it is just a username but can add more fields like age etc. for further implementation.

In server.js we will receive the following emitted event above like this:

//new users 
socket.on("new-user", function(data, callback) {
 console.log("new users data", data);
 callback(true); socket.username = data;
 console.log("socket username", socket.username);
 users.push(socket.username);
 console.log("users array", users);
 updateUserNames();
}); 
function updateUserNames() {
 io.sockets.emit("get-users", users);
}

Adding him to the list of existing users this code is part of existing on the connection method. Here data is username coming from UI, we set the associated socket with the data(username) and calls a function which emits the details of users(all).

We will also update our existing disconnect function when the socket user is disconnected from the page.

//disconnect 
socket.on("disconnect", function(data) {
 if (!socket.username) return;
 users.splice(users.indexOf(socket.username), 1);
 updateUserNames();
 connections.splice(connections.indexOf(socket), 1);
 console.log("Disconnect %s:", connections.length);
});

Here we are removing the disconnected user from the list of users and updating the list of users if the current associated user which is disconnected this means he has to enter a new username if he/she wants to rejoin the chat.

While for updating the user list on UI to show and updating whatever new messages we are receiving from all the connected socket user we will add the below code to index.html

//updating UI on new connection 
socket.on("get-users", function(data) {
 var userHtml = "";
 data.forEach(function(each, index) {
   userHtml += '<li class="list-group-item list-item">' + each + "</li>";
 });
 users.innerHTML = userHtml; 
}); 
//updating UI on new message 
socket.on("new-message", function(event) {
 var divTag = document.createElement("div");
 divTag.innerHTML = '<div class="chat-row"><strong>' + event.user + ":</strong>" + "<span>" + event.message + "</span></div>";
 fragment.appendChild(divTag);
 chatBox.appendChild(fragment); });

Here we have it, fully working chat application where users can interact in real-time share messages. A further upgrade on this can be an authenticated login and features like sharing a file. This is just a place to start there are many cool things which uses Socket.io. Companies use this for things like push notifications, chat application. So to simply put it can be used anywhere where we need any real-time communication and various other scenarios like online file sharing, a multiplayer gaming portal, etc.

Click here to find the missing code: SocketIO

Thanks for reading!

About The Author