Real Time Communication Using Socket.IO

We will create a very basic real-time chat application using Socket.IO. We will only focus on the implementation, how the communication happens, and understanding the flow of it, nothing else.
First Things First
Check if Node.js and NPM are installed. Run the following on your terminal to check-
node -v npm -v
If both are installed, it will show you the current version of it. If not, you know what to do.
Create a folder and open it in VS Code (or use any IDE you like, who cares).
Open your terminal, navigate to the folder (or directly open the terminal on the IDE), and run ‘npm init’.
Create two files, ‘index.js’, and ‘chat-page.html’ (give any name you like; I’m naming it socket.html).
Now, we can start coding :)
1. Create a Server
First, we need to create a server that will serve our chat app. Open your ‘index.js’ file and write the following code.
Then open the terminal and run ‘npm install express’ (you have to be inside your project folder). If you don’t understand the above code, then help yourself.
Now, if you run ‘
node index.js’,
you should see the following on your terminal.
I’m adding the code snapshots so that you can’t just copy and paste them. Move your lazy fingers.
2. Create the HTML Page for the Chat App
Now, we need an HTML page to show and type our messages.
Open the HTML file and write the following code.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Easy Chat</title>
</head>
<body>
<h1>Easy Chat</h1>
<ul id="messages"></ul>
<form id="form" action="">
<input id="input" autocomplete="off" /><button>Send</button>
</form>
</body>
</html>
You can copy the HTML code. We are not worried about how the page looks.
If you open the ‘index.html’ file in the browser, it should look like the following-
2.1 Connect the HTML Page with the Server
We have created our server and the chat web page. Now, we have to connect them so that when we start our server, we can see our web page in the browser. Add the following code to your ‘index.js’ file-
Open your terminal and run ‘npm install path url’
To connect our HTML page with the server, we need to get the file path first. Here, we are storing the file directory path in the ‘_dirname’ variable. Then we send the ‘socket.html’ page in response when the server is started. It means when we search localhost:3000
in the browser, we should see the HTML page.
Now, run ‘node index.js’ again in the terminal and then search localhost:3000 in the browser. You should see the following-
So far, your code should look like the following:
3. Adding Socket.IO
First, we need to make some changes in our index.js file. Let’s see the changes first:
We have made changes in lines 2, 7, and 17. We have created an instance of an HTTP server and bound it to Express. Why? Because socket.io expects an HTTP server, not the Express instance.
Now, we have to create an instance of socket.io and attach it to the HTTP server.
const io = new Server(server);
Server Side Connection
Install socket.io: npm install socket.io
Add the following code to your index.js file:
io.on('connection', (socket) => {
console.log('user connected: ', socket.id);
});
Here, the server is listening for the ‘connection’ event to detect any incoming socket and log it to the console. But what would the server do when it receives any socket? We will talk about it soon. Have some patience!
Client Side Connection
Now, add the following code to your index.html file:
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
</script>
<script src="/socket.io/socket.io.js"></script>
This line loads the Socket.IO client-side library, the browser version of Socket.IO. When we install and use socket.io, the server automatically makes this file available at /socket.io/socket.io.js.
It’s not a local file in our project; it is served automatically by the socket.io server middleware.
Okay…Pause
Before coding further, let’s understand the flow from the client side.
What should happen when we send a message? We should see the message on our web page. We will do that using DOM (Document Object Manipulation). Then we need to emit that message to our server so that our server can send the message to the connected users on our server.
One more thing left, can you guess?
We also need to listen to the socket event for any incoming sockets (messages for us) from the server, and show the message on our web page.
Now, you can add the following code to your index.html page.
<script>
const socket = io();
const form = document.getElementById('form')
const input = document.getElementById('input')
const messsages = document.getElementById('messages')
form.addEventListener('submit', (e) => {
e.preventDefault();
if(input.value){
//from client, emit the event to the server
socket.emit('chat message', input.value);
input.value = '';
}
})
socket.on('chat message', (msg) => {
//Listening for server events: every client will receive the event broadcasted by the server
const item = document.createElement('li');
item.textContent = msg;
console.log(msg);
messages.appendChild(item); //add the message to the ui
})
</script>
Our form will respond when a submit event occurs(sending a message), and it will emit the input value to the server. Then our server will receive that socket and broadcast it to all the connected users, including us (We haven’t completed that part yet). We will catch that event on the client side (using socket.on) and display the message on the web page.
Your index.html file should look like the following:
Completing the Server Side
I hope we have an overall picture of the flow. Now we know that when our server receives any sockets, it needs to send those sockets to the connected users.
Complete your index.js file:
// listen on the 'connection' event for incoming sockets
io.on('connection', (socket) => {
console.log('user connected: ', socket.id);
socket.on('chat message', (msg) => {
io.emit('chat message', msg); //broadcast to all clients
console.log("User message: " + msg);
});
});
Here, we will receive any incoming sockets in the ‘msg’ argument and, using ‘io.emit’, we will broadcast it to all the clients.
And we are done!
Final index.js code:
Now, Open two tabs side by side and test the app.
Let’s Understand the Flow Again :D
Starting the Server
const io = new Server(server);
It creates a webSocket server and start listening for incoming socket connections over the same server.
Browser Loads the Clietn Script
<script src="/socket.io/socket.io.js"></script>
The browser loads the Socket.IO client library.
Client Calls io() to Connect
const socket = io();
The browser makes an initial HTTP request and open a persistent bi-directional connection. This connection stays open and any side can emit events at any time.
Server Detects the Connection
io.on("connection", (socket) => { console.log("Client connected", socket.id); });
The server calls the
connection
handler, which gives ansocket
object representing that one unique client. Each client gets its socket instance.Communication
Client → Server:
socket.emit("chat message", "Hello!");
Server → Client:
socket.on("chat message", (msg) => { io.emit("chat message", msg); });
This article is to help you get started with Socket.IO. There is much more, and you should start exploring.
To know more about Socket.IO: https://socket.io/docs/v4/tutorial/introduction
The art of life is more like the wrestler’s art than the dancer’s, in respect of this, that it should stand ready and firm to meet on sets which are sudden and unexpected.
Marcus Aurelius
Subscribe to my newsletter
Read articles from FarhaN Asfar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
