WebSockets
Tags: react, javascript, html, express
Published: 2024-03-15 12:04:31

A WebSocket is a communication protocol that provides full-duplex communication channels over a single TCP connection. It enables a real-time, event-driven connection between a client and a server.

"Full duplex" refers to the capability of a communication system to transmit data in both directions simultaneously. In the context of a WebSocket connection, it means that both the client and the server can send and receive data at the same time without having to wait for each other to finish transmitting.

![websocket connection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f9i7w40h6thuzn1pz2vc.png)
(Image Source: Internet)

### Best React WebSocket libraries

1. Socket.IO: It is a widely used library that provides real-time bidirectional event-based communication between the browser and the server. It offers features like automatic reconnection, fallback options, and support for various transports, making it an excellent choice for building scalable and reliable applications. Socket.IO supports multiple programming languages, including JavaScript, Python, and Java.
2. SockJS is a JavaScript library that provides a WebSocket-like object in the browser, even if the server doesn't support WebSockets. It offers a fallback mechanism that uses alternative transport protocols, such as HTTP long-polling, allowing your application to work in environments where websockets are unavailable. SockJS can be used with various backends and programming languages, including Node.js, Java, and Python.
3. WS is a simple and lightweight WebSocket implementation for Node.js. It provides a straightforward API for creating WebSocket servers and clients, making it easy to integrate websockets into your Node.js applications. ws offers per-message compression, automatic reconnection, and customizable options for handling incoming and outgoing messages.

### How WebSocket works in simple words

In the case of WebSocket there a handshake will happen between the client and the server and there server tells that I am going to share an HTTP upgrade request. What it meant by is, I am going to upgrade the connect to websocket. Then a connection will open which can help in having bidirectional requests. HTTP is going to be upgraded using method 101(used to change your network protocol)

### Example

This is a real-time live comment section where all the live comments are broadcast. And in the demo project, I am using socket.io.

- We will create a normal HTML file and run the script in the script tag, where we will call io().
    - io(): This is a function provided by the Socket.IO library. It creates a WebSocket connection to the server.
    - In the client, we listen to a 'chat message' event and when we receive a message then show it in the UI.

```
<!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>
    <style>
      body {
        margin: 0;
        padding-bottom: 3rem;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          Helvetica, Arial, sans-serif;
      }
      #form {
        background: rgba(0, 0, 0, 0.15);
        padding: 0.25rem;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        display: flex;
        height: 3rem;
        box-sizing: border-box;
        backdrop-filter: blur(10px);
      }
      #input {
        border: none;
        padding: 0 1rem;
        flex-grow: 1;
        border-radius: 2rem;
        margin: 0.25rem;
      }
      #input:focus {
        outline: none;
      }
      #form > button {
        background: #333;
        border: none;
        padding: 0 1rem;
        margin: 0.25rem;
        border-radius: 3px;
        outline: none;
        color: #fff;
      }
      #form > button:hover {
        cursor: pointer;
        background-color: #0f0e0e;
      }
      #messages {
        list-style-type: none;
        margin: 0;
        padding: 0;
      }
      #messages > li {
        padding: 0.5rem 1rem;
      }
      #messages > li:nth-child(odd) {
        background: #efefef;
      }
    </style>
    <script src="/socket.io/socket.io.js"></script>
  </head>
  <body>
    <h1>Subham's websocket app</h1>
    <ul id="messages"></ul>
    <div style="position: absolute; bottom: 5px">
      <body>
        <ul id="messages"></ul>
        <form id="form" action="">
          <input id="input" autocomplete="off" /><button>Send</button>
        </form>
      </body>
      <script>
        const socket = io();
        const form = document.getElementById("form");
        const input = document.getElementById("input");
        const message = document.querySelector("#messages");

        form.addEventListener("submit", (e) => {
          e.preventDefault();
          if (input.value) {
            socket.emit("chat message", input.value);
            input.value = "";
          }
        });

        socket.on("chat message", (msg) => {
          const item = document.createElement("li");
          item.textContent = msg;
          message.appendChild(item);
        });
      </script>
    </div>
  </body>
</html>
```
> Note: I am adding the Backend code for better understanding.

- Let us implement a simple Backend that will broadcast the messages/comments

```
const express = require("express");
const { createServer } = require("node:http");
const { join } = require("node:path");
const { Server } = require("socket.io");

const PORT = 3010;
const app = express();
const server = createServer(app);
// The Server class extends the functionality of the provided HTTP server to handle WebSocket connections alongside regular HTTP requests.
const io = new Server(server);

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

// This line listens for the 'connection' event emitted by clients when they establish a WebSocket connection to the server. When a client connects to the server, this event is triggered.
io.on("connection", (socket) => {
  console.log("Connection established");
  //  This line sets up an event listener on the socket object for the 'chat message' event. When the client sends a 'chat message' event to the server, this listener is triggered.
  socket.on("chat message", (msg) => {
    console.log("received message", msg);
    io.emit("chat message", msg);
  });

  socket.on("disconnect", () => {
    console.log("User disconnected!");
  });
});

server.listen(PORT, () => {
  console.log("server running at http://localhost:3010");
}); 

```

Here in the demo screenshot, I have opened 2 tabs and from 1st tab, I commented "Hi" and from another, I commented "hello"

![websocket implementation screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xu1swsm5vahkvjqzu2bj.png)

### Challenges to consider while implementing

- Resource usage
- Connection limits
- Load balancing
- Authentication
- Firewall/Proxy
- Scaling
- Testing/Debugging
- Resource cleanup
- Error handling

### Applications of WebSockets

- Chat Applications
- Live Feeds and Notifications
- Online Gaming
- Financial Trading Platforms
- Real-Time Analytics and Monitoring
- Live Streaming and Broadcasting


I have tried to explain all the details of SSE that I know.

> Thanks For Reading, Follow Me For More