Building Interactive Real-Time Apps with Socket.IO in Node.js:
Tags: node, socketio, socket, javascript
Published: 2023-09-04 22:49:02

## **Introduction**

In the world of web development, creating real-time applications has become increasingly important. Users expect instant updates and interactivity in web applications, whether it's for online gaming, chat applications, or collaborative tools. To meet these demands, developers often turn to technologies that enable real-time communication, and one such technology is Socket.IO.

Socket.IO is a JavaScript library that allows bidirectional (the ability for data to flow in two directions or to be exchanged between a client), event-driven communication between clients (usually web browsers) and servers. It's particularly popular for building real-time applications because it abstracts the complexity of dealing with low-level WebSocket connections while providing a simple and efficient API for developers. 

Socket.IO achieves bidirectional communication by establishing a persistent connection between the client and server, often using technologies like WebSockets. This connection allows data to be pushed from the server to the client (server-to-client or S2C) and from the client to the server (client-to-server or C2S) without the need for the client to continually poll the server for updates.

In this article, we will explore how to implement Socket.IO in a Node.js application.

Setting Up a Node.js Project

Let's start by creating a new Node.js project. To create a Nodejs application, run the following commands in your terminal:

Create a project folder:

```
mkdir socket-io-demo 
```

```
cd socket-io-demo
```

Initialize a new Node.js project:

```
npm init -y
```

Install express and Socket.IO library:

```
npm install express socket.io
```

Setting Up the Server

Create a Javascript file (`server.js`) in your project directory to set up the Nodejs server. Your server.js file will contain the code below:

```
// Import modules
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

// Initialize app and server 
const app = express();
const server = http.createServer(app);
const io = socketIo(server);

const PORT = process.env.PORT || 3000;

// Create a simple route for HTTP GET requests
app.get('/', (req, res) => {
  res.send({ message: 'This server is running.' });
});

// Connect to socket
io.on('connect', (socket) => {
  console.log('A user connected.');

  socket.on('newMessage', (message) => {
    io.emit('message', message);
  });

  socket.on('disconnect', () => {
    console.log('A user disconnected');
  });
});

server.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
```


In the first three lines, we import the modules we'd be needing for our nodejs socket implementation:

```
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
```

This first line of code imports the Express.js framework into the Node.js application. Express.js is a popular and widely used web application framework for Node.js. It simplifies the process of building web applications by providing a set of robust and flexible tools for routing, handling HTTP requests and responses, and managing middleware. By requiring 'express', the entire Express.js framework is made available for use in our application. The `http` module imported in the second line is a built in Nodejs module that provides functionality for creating HTTP servers and handling HTTP requests and responses, In our specific use case, we are using it to create an HTTP server that will serve our Socket.IO-based chat application over HTTP. The third line imports the Socket.IO library into our Node.js application.

The next step will be to create an instance of our Express.js application by invoking the express() function. 

```
const app = express();
```

The app variable now represents our Express.js application.

In the next line, we create an http server using 'http.createServer()' method provided by the built-in 'http' module, this will handle http requests made to the application.

```
const server = http.createServer(app);
```

The `app` object, which is an instance of Express.js, is passed as a parameter to `http.createServer()`, which means that your Express.js application will be used as the request handler for this HTTP server.

We then integrate Socket.io with our server, thus:

```
const io = socketIo(server);
```

The 'socketIo' variable represents the Socket.IO instance, and we pass our HTTP server (server) created in the previous line as a parameter to socketIo() to create a WebSocket server.

We then go further to set our port and a simple root handler for HTTP GET requests when a client accesses the root URL of the server. This just returns a simple message: 

> This server is running.
 to the requesting client.

```
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.send({ message: 'This server is running.' });
});

```
We then write our event listeners and logic to connect, receive and broadcast messages among clients.

```
// Connect to socket
io.on('connect', (socket) => {
  console.log('A user connected.');

  socket.on('newMessage', (message) => {
    io.emit('message', message);
  });

  socket.on('disconnect', () => {
    console.log('A user disconnected');
  });
});

io.on('connect', (socket) => {
```

This line sets up an event listener for the `connect` event. When a client (such as a web browser) establishes a connection to the Socket.IO server, this event is triggered. The callback function, which takes a socket object as a parameter, is executed when a new client connects.

```
socket.on('newMessage', (message) => {
```

Within the 'connect' event handler, this line sets up an event listener on the socket object for an event named `newMessage`. This means that the server is listening for `newMessage` events sent by the connected client. When a `newMessage` event is received, the callback function is executed, and the message parameter contains the data sent by the client. The message parameter can be a string, object or any other kind of data type that you might want to transmit. One other thing to note:

Your server, once connected, listens to all events defined within the `connect` event handler. 

```
io.emit('message', message);
```

Inside the `newMessage` event handler, this line broadcasts the received message data to all connected clients using the `message` event. The `io.emit()` method sends the message to all clients connected to the Socket.IO server, ensuring that everyone receives the same message in real-time. Since we are expecting a string as the `message` parameter, we can just resend it, the message parameter can contain the user details including the message sent and can be used as desired.

You can create other event listeners within your `connect` event handler to handle other events that might be needed in your Nodejs socket application.

```
socket.on('disconnect', () => {
```

This part of the code sets up an event listener for the `disconnect` event. The `disconnect` event is triggered when a client disconnects or closes their connection to the server.

```
console.log('A user disconnected');
```

Inside the `disconnect` event handler, this line logs a message to the server's console to indicate that a user has disconnected. Similar to the 'A user connected' message, this provides information about user interactions with the server.

Finally, we start our server:

```
server.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

server.listen(PORT, () => {
```

`server:` This refers to the HTTP server that was created earlier in the code using http.createServer(app).

`.listen(PORT, ...:` This is a method used to start the server and make it listen on a specific port for incoming network requests. PORT is a variable that holds the port number on which the server should listen. Earlier on, we defined our port to either use PORT set in our .env file or 3000.

`() => { ... }`

This part is an arrow function (ES6 syntax) that serves as a callback function. The callback function is executed once the server has successfully started and is listening on the specified port.

`console.log(Server is running on port ${PORT});`

Inside the callback function, this line logs a message to the console. The message indicates that the server has successfully started and is now running on the specified port. 

With these steps, we have set up our Socket Server Application. Run the following command within your socket-io-demo directory to start the server:

```
node server.js
```

The following screenshot shows a simple implementation of our Client-side Socket application:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sthg8gq2utxjr4gbvzo7.png)

Client Side Socket implementation.

The Client-Side app connects to the Socket using the server URL/IP address and the port. Line 11 listens for any message event and logs it on the client's.

Line 17: Calls the sendMessage event to send a new message to all connected users. 

This article is meant to introduce you to Socket.io, the implementation here can be tweaked to suit what you want as a developer. You can check the socket Documentation to learn more about sockets.

Thank you for engaging with the content, and happy hacking!