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.
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.
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 express
Code 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.js
Code language: Bash (bash)
On navigating to the root route, we will get the string Hello from Codedamn
as a response,
Installing Socket.IO
We can install Socket.IO using the NPM package manager by entering the command
npm install socket.io
Code 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,
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,
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.
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,
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,
- A real-time multiplayer game.
- A real-time upvotes counter like reddit.com.
- A collaborative coding platform with real-time updates to all the connected clients.
- 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.
No comments so far
Curious about this topic? Continue your journey with these coding courses: