Socket-IO for Beginners
Tags: node, webdev, tutorial, socketio
Published: 2024-05-30 10:41:59


- **Socket-IO:** Socket.IO is an open-source, cross-platform library that provides full-duplex bidirectional communication between a client and a server based on events.

**Why Socket-IO is needed?** 

- **Traditional Client-Server Model**

In the traditional client-server architecture, the communication follows a request-response pattern. The client sends a request to the server, and the server processes this request and sends back a response. After this exchange, the connection is closed. This model has a significant limitation: the server cannot initiate communication with the client. If the server needs to send additional data or updates to the client, it has no way to do so without the client first making a request.


![client-server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vi5k10teby6brjlsi909.png)



- **Example:** Consider a chat application built using the traditional model. When a user (client) sends a message, it goes to the server. The message is then stored on the server, waiting for the recipient (another client) to request it. The recipient will only receive the message when they make a new request to the server. This creates a delay in message delivery, as shown below:


![chat app fig](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0icfrhmi7ue2vypynm3v.png)


- One way to address this issue is through **Polling**. Polling involves clients making periodic requests to the server at fixed intervals to check for new data. While this ensures that clients eventually receive updates, it introduces significant latency and connection overhead. Constantly opening and closing connections for each request consumes resources and can lead to delays, especially under heavy load.


![pooling architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dc9uqp6ldciulmyw2z46.png)


- Thus to overcome these limitations, WebSockets were introduced.

- Web Socket : WebSocket is a computer communications protocol, providing a simultaneous two-way communication channel over a single Transmission Control Protocol (TCP) connection. 

**How Web-socket actually works??**

- During the initial connection setup, the HTTP header includes an Upgrade field, which facilitates the transition from an HTTP connection to a WebSocket connection.

- **Upgrade**: The HTTP 1.1 (only) Upgrade header can be used to upgrade an already established client/server connection to a different protocol (over the same transport protocol). For example, it can be used by a client to upgrade a connection from HTTP 1.1 to HTTP 2.0, or an HTTP or HTTPS connection into a WebSocket.


![ws diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a54qu0inrluswh7b9wpx.png)

- Thus doing this the WebSocket connection is established and now the connection will work in full duplex mode and in order to make the web socket implementation easy there is library called **socketio**.

- Socket.IO builds on WebSockets and provides a more robust, scalable solution for real-time communication. It supports bidirectional, event-based communication, allowing both the client and server to send and receive messages instantly. Socket.IO also includes fallback mechanisms, ensuring reliable communication even if WebSockets are not supported.

- By using Socket.IO, we can create real-time applications like chat systems where messages are instantly delivered to all connected clients without the need for repeated requests.


## <u>Let us make a basic chat app using Node and Html</u> 

- index.js : 

```
const express = require('express');
const http = require('http');
const port = 3000;
const path = require('path');
const {Server} = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

io.on('connection', (socket) => {
    socket.on('user-message', (msg) => {
        io.emit('message', msg);
    }
    );
});


app.use(express.static(path.join(__dirname, 'public')));


app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});



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

```

- index.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>Chat App</title>
 
</head>
<body>
    <h1>Chatting</h1>

    <div>
        <input type="text" id="message" placeholder="Enter Message" />
        <button id="sendBtn">Send</button>
    </div>

    <div id="messages"></div>

    <script src="/socket.io/socket.io.js"></script>
    <script>
        const socket = io();
        const sendBtn = document.getElementById("sendBtn");
        const messageInput = document.getElementById("message");
        const allMessages = document.getElementById("messages");

        socket.on("message", (message) => {
            const p = document.createElement("p");
            p.innerText = message;
            allMessages.appendChild(p);
        });

        sendBtn.addEventListener("click", (e) => {
            const message = messageInput.value;
            console.log(message);
            socket.emit("user-message", message);
            messageInput.value = ''; // Clear the input field after sending
        });
    </script>
</body>
</html>

```
- You can get the complete code [here](https://github.com/jemmyasjd/SocketIO)

- After running the code you may get the connection details by doing inspect to the network section as shown below where you can see the header contains the connection to upgrade and the upgrade field contains the websocket. 

![network details](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/spre0u4cx1896sf4rkd6.png)

- Code explanation : 

   - Server Setup:
The server listens for new client connections using `io.on('connection')`.
When a new client connects, the server sets up custom event listeners on the client's socket using `socket.on`.
   
   - Client-Side Events:
Clients send events to the server using `socket.emit`. For instance, when a user sends a chat message, the client emits a 'user-message' event to the server.

    - Server Handling and Broadcasting:
The server receives the event using `socket.on('user-message')` and processes the data (e.g., the chat message).
The server can then broadcast this message to all connected clients using `io.emit('message', msg)`, ensuring that every client receives the new chat message instantly.


- Code Output: 


![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1aeu061fplui3qqyhijr.png)

## <u>Conclusion</u>

In summary, Socket.IO provides a solution for real-time, bidirectional communication between clients and servers, overcoming the limitations of traditional client-server models. By leveraging WebSocket technology, Socket.IO facilitates instant message delivery without the need for constant polling, reducing latency and connection overhead. Through a simple example of building a chat app with Node.js and HTML, it demonstrated how Socket.IO enables seamless real-time communication. Its ease of use, flexibility, and robustness make it an invaluable tool for developers looking to build dynamic web applications with interactive features.