How to use socket.io with Node.js – Node.js Socket.io Complete Tutorial

How to use socket.io with Node.js – Node.js Socket.io Complete Tutorial

We all are familiar with real-time messaging applications and use them quite often. These have become a part of our life. But did you ever thought about how these realtime-applications built? It’s because of Socket.IO

We know that we use an HTTP request to transfer any message/data from our client to a server. The HTTP protocol is an application protocol that uses the TCP protocol, which requires a three-way handshake to connect the client and the server successfully. After the data transfer is complete, the connection is closed.

HTTP lifecycle

There is one-way communication between the client and server because HTTP is a unidirectional protocol. HTTP is a stateless protocol that means every time we make a request, a three-way handshake is performed, which increases the delay in response. But for real-time communication, we cannot afford any delay. Thus, we need a persistent connection between the client and the server. WebSockets can help us to tackle this situation.

WebSocket is a bidirectional, full-duplex protocol, as opposed to HTTP. It is a stateful protocol, meaning it will maintain the connection between the client and server until either party terminates it. Since the connection is persistent, real-time communication between the client and the server is possible.

WebSocket lifecycle

What is Socket.IO?

Socket.IO is a library that allows clients and servers to communicate in real-time, bidirectionally, using an event-driven architecture.

Socket.IO server and client implementations are available for all the major languages like JavaScript, Java, Python, Go, etc.

It has a ton of great features. Few of them are,

? HTTP long-polling fallback

The server uses HTTP long-polling whenever it cannot establish a WebSocket connection. Long polling is similar to regular polling, in which the client requests information from the server. However, suppose the server does not have any information available for the client. In that case, the server will hold the request and wait to receive information before sending a complete response to the client (or until a suitable timeout event occurs).

? Automatic reconnection

Suppose, due to some circumstances, the WebSocket connection between the client and the server gets interrupted. The client eventually disconnects and automatically reconnects after an exponential backoff delay to not overwhelm the server.

? Packet buffering

When the client disconnects, packets are buffered and sent upon reconnecting.

Setting up Socket.IO using Node.js and Express.js

Socket.IO is an event-driven architecture. That means we will listen for some events on both the client and the other server. Whenever an event gets triggered on either the client or the server side, we will run a callback which might emit some more events. We will be setting up Socket.IO for both the client and the server.

Setting up Socket.IO on the server

We will divide our setup of Socket.IO into several steps. As a result, we will be able to get a general idea of how a Socket.IO server is structured.

Setting up Express.js

Before moving to the setup of Socket.IO, let’s set up a simple Express.js application first,

# Initialize the project
npm init

# Install dependencies
npm install expressCode language: Bash (bash)

Create an index.js file with the following contents,

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    res.send('Hello from Codedamn');
})

const server = app.listen(1337, () => {
    console.log('Server running!')
})Code language: JavaScript (javascript)

The above code will create a basic Express.js server. We will start our server using,

node index.jsCode language: Bash (bash)

On navigating to the root route, we will get the string Hello from Codedamn as a response,

A basic Express.js server

Installing Socket.IO

We can install Socket.IO using the NPM package manager by entering the command

npm install socket.ioCode language: Bash (bash)

Listening to a connection

Now that we have Socket.IO installed and a basic Express.js server set up, we want to listen for connections from clients. As soon as a client connects to our server, a server-side event is fired, and we will execute some operations and set up some more event listeners.

To set up Socket.IO, we must mount it on our Express.js server so that we can listen to events. We do so by writing the following code in our index.js,

const express = require('express');
const socketio = require('socket.io');

const app = express();

app.get('/', (req, res) => {
    res.send('Hi from Codedamn')
});

const server = app.listen(1337, () => {
    console.log('Server running!')
});

const io = socketio(server)

io.on('connection', (socket) => {
    console.log('New connection')
})Code language: JavaScript (javascript)

We provided the server instance to the Socket.IO library so that it can mount on top of it. Socket.IO can now watch for connections to our socket server and will fire the connection event. We will listen for the connection event and run a callback whenever the event is fired. The callback will receive a socket object that will contain all details about the client that is connected. Each client will be assigned a unique ID which we can access through the socket object using socket.id.

Setting up Socket.IO on the client

Similar to what we did for the server setup, we will divide the setup of Socket.IO on the client side into several steps. As a result, we will be able to get a general idea of how to structure Socket.IO on the client side.

Setting up the index.html

Inside the root directory, create a directory named client. Inside the client directory, create an index.html file with some boilerplate HTML,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Hi from Codedamn</h1>
</body>
</html>Code language: HTML, XML (xml)

Serving the index.html page to the client

To render an HTML page using Node.js, we use the res.sendFile() function. Let us render the index.html file we create,

const path = require('path');

app.get('/', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'client', 'index.html'));
});Code language: JavaScript (javascript)

Serving static assets from our Express.js server

Since we have created our client folder, we must tell express that this directory is a public one. To do this, we will write the following code in our server’s index.js file before our route handlers,

app.use(express.static(path.resolve(__dirname, 'client')));Code language: JavaScript (javascript)

Getting the Socket.IO library on the client

The client-side library of Socket.IO, socket.io-client, will be available on the /socket.io/socket.io.js route on our server, which we can access through our HTML file using the script tag,

<script src="/socket.io/socket.io.js"></script>Code language: HTML, XML (xml)

Now a global io function will be defined. We will use it to connect to the socket server. The function takes the URL of the socket server as an argument and returns a Socket object on a successful connection.

Connecting to the socket server

We can connect to the socket server using the globally defined io method. The io method requires the URL of the socket server as its argument. As we will only be serving HTML from our socket server, there is no need to pass any arguments since the default argument will be taken into account.

Create a script.js file inside the client directory. To connect to our socket server, we will write the following inside the script.js we just created,

const socket = io();Code language: JavaScript (javascript)

Now, reference the script.js file in our index.html file,

<script src="/script.js"></script>Code language: HTML, XML (xml)

As soon as we start our socket server and navigate the root route, the client will establish a Web Socket connection with the server. We will see a console log on the server that a new client is connected,

The successful connection between the client and the server

We can also log the client’s socket ID using,

io.on('connection', (socket) => {
    console.log(`New connection: ${socket.id}`);
})Code language: JavaScript (javascript)

On restarting the server and navigating to the root route, we can also see the client’s socket ID on the console,

Logging connected client’s socket ID

Passing messages between client and server

Now that we have set up Socket.IO on both the server and the client, we can pass messages between them. Since Socket.IO has an event-driven architecture, we would need to listen for the events on both the server and the client. We can pass messages between the two by emitting certain events from one side and listening to them on the other.

Setting up an event listener on the server

On a successful connection, we run a callback that receives an socket object as its argument. The socket object contains the client’s details and some methods to set up event listeners on the server.

NOTE: Apart from standard events, we can also listen to our custom events.

To set up an event listener, we will use the following syntax,

socket.on('EVENT NAME', (data) => {
  // Do stuff        
})Code language: JavaScript (javascript)

Let us set up an event listener that listens for a message event,

io.on('connection', (socket) => {
    console.log(`New connection: ${socket.id}`);

    socket.on('message', (data) => {
        console.log(`New message from ${socket.id}: ${data}`);
    })
})Code language: JavaScript (javascript)

Now, whenever a client emits a message event, we will get a console log on our server.

Emitting events from the client

We can use the socket object that was returned from the io method to set up event listeners and emit various events we have defined on our server.

To set up an event listener, the syntax remains the same as we did on the server. To emit an event, we will write

socket.emit('EVENT NAME', data);Code language: JavaScript (javascript)

Let us emit the message and see what happens. Add the following line of code to your client/script.js file,

socket.emit('message', 'Hi');Code language: JavaScript (javascript)

Here message is the event name, and Hi is the string we want to send as data. Restarting the server and navigating to the root URL shows a log on the server console that a new client is connected and the message the client sent.

Emitting message event from the client

As soon as the client connects to the server, it emits a message event. The callback corresponding to the message event gets fired, and we see a console log with the client’s message.

Setting up an event listener on the client

In the same way that we set up the event listeners on the server, we can do the same on the client.

Let us set up an notification event listener on the client

socket.on('notification', (data) => {
    console.log(`New notification: ${data}`);
})Code language: JavaScript (javascript)

Now, whenever the server emits an notification event, we will get a console log on our browser.

Emitting events from the server

We will emit events from the server in the same way as the client. Let’s say that whenever a client connects with the server, we will emit a notification event to the client. To achieve this, we will write the following code in our index.js,

io.on('connection', (socket) => {
    console.log(`New connection: ${socket.id}`);

    socket.emit('notification', 'Thanks for connecting to Codedamn!')

    socket.on('message', (data) => {
        console.log(`New message from ${socket.id}: ${data}`);
    })
})Code language: JavaScript (javascript)

On restarting the server and navigating to the root URL, we can see a log on the client’s browser console,

Emitting notification event from the server

What can you build with Socket.IO?

Various applications utilize Soctket.IO for real-time messaging and data transfer between the client and the server. For instance, Chat Applications use real-time messaging and data transfer to update the new messages and data instantly. Other cool things you can try out could be,

  1. A real-time multiplayer game.
  2. A real-time upvotes counter like reddit.com.
  3. A collaborative coding platform with real-time updates to all the connected clients.
  4. A teaching platform with a doodle board that updates in real-time.

These are some suggestions, but there are many use cases of Socket.IO.

How to get help with Socket.IO

For learning advanced concepts like broadcasting, etc., or for more complex use cases, you can refer to the Socket.IO documentation. The documentation covers everything you need to know about Socket.IO, from basic to advance. It contains everything you need to start your first Socket.IO application.

Conclusion

In this article, we discussed the WebSockets protocol and how it helps establish real-time communication between the client and the server. We looked at what Socket.IO is and how it makes it easy to work with WebSockets. Further, we discussed setting up Socket.IO on the server and the client. Finally, we saw how to utilize Socket.IO for real-time message/data passing between the client and the server.

Thank you so much for reading ?

Sharing is caring

Did you like what Varun Tiwari wrote? Thank them for their work by sharing it on social media.

0/10000

No comments so far