Introduction to websockets | Building a real-time chat application in Node.js

Subhradip SinhaSubhradip Sinha
5 min read

In today’s world of live streaming, video conferencing, and remote work, latency is a major concern for users. A smooth, uninterrupted experience is crucial.

Traditional HTTP, which relies on client requests, struggles to meet this demand. It's simply too slow and needs an upgrade—"literally!!!".

Here websockets enters💪, A web-friendly, event-driven alternative to HTTP. Unlike HTTP, WebSockets don’t require constant client requests to retrieve data, making them ideal for real-time updates. Curious how this works? Let’s explore.

What Are WebSockets?

In simple terms, WebSockets are an enhancement to traditional HTTP.

When a WebSocket request is made over HTTP, the connection is upgraded to a WebSocket connection at the protocol level. This means that while the protocol changes, the underlying TCP connection remains the same as it was under HTTP.

To use a WebSocket, the client first sends a request to upgrade the server.

If the server supports WebSockets (which most do nowadays), it will accept the request and switch the protocol from HTTP to WebSocket.

Once this protocol switch is successful, the HTTP server becomes a WebSocket server, establishing a persistent connection between the client and server.

The WebSocket server then waits for events to trigger, performing the relevant function when they do. For instance, in a chat application, you don’t need to request new messages constantly. Thanks to the WebSocket connection (which is event-driven), the server automatically pushes every new message (event) directly to the client.

WebSockets are especially useful in scenarios requiring real-time updates, such as:

  • Chat applications

  • Location-based apps

  • Social feeds

  • Collaborative workspaces

  • Multiplayer gaming

  • Live streaming

  • Financial and sports updates

Additionally, headers in WebSockets are sent only once during the upgrade request, resulting in speeds 5-7 times faster than traditional HTTP. YEah u r RIGHT!!! I GOOGLED IT :)

Exciting, right? Lets build a real time chat application based on express server.

Setting Up the Development Environment

First, we need to set up our development environment by installing the necessary files and packages and creating our workspace. We’ll use the ws library to build a simple chat application using WebSockets in Node.js.

  1. In your project folder, create two folders named client and server.

  2. Open your terminal, navigate to the server directory, and run the following commands one by one:

     npm init -y
     # Initializes Node.js
    
     npm install websocket
     # Installs the WebSocket library
    
     npm install ws
     # Installs the ws library
    
     npm install express
     # Installs Express
    
     npm install nodemon
     # Installs Nodemon (not necessarily)
    
  3. After installing these packages, create a file named index.js inside the server folder. This will be our server-side JavaScript file.

  4. Next, move on to the client folder. Here, create two files: index.html (the frontend for our application) and script.js (the client-side JavaScript file).

With this setup complete, you’re ready to start building your WebSocket-powered application.

Implementing the Server

Let’s start by coding the server-side JavaScript. Add the following code to the index.js file inside the server folder:

const WebSocket = require("ws");
const express = require("express");
const app = express();
const path = require("path");

app.use("/", express.static(path.resolve(__dirname, "../client")));

const myServer = app.listen(9876);  // HTTP server using Express to serve your webpage

const wsServer = new WebSocket.Server({
    noServer: true
});  // WebSocket server

wsServer.on("connection", function(ws) {  // Handle WebSocket connection
    ws.on("message", function(msg) {      // Handle message event
        wsServer.clients.forEach(function each(client) {
            if (client.readyState === WebSocket.OPEN) {  // Check if the client is ready
                client.send(msg.toString());
            }
        });
    });
});

myServer.on('upgrade', function upgrade(request, socket, head) {  // Handle HTTP to WebSocket upgrade
    // Randomly accept or reject connections
    if (Math.random() > 0.5) {
        return socket.end("HTTP/1.1 401 Unauthorized\r\n", "ascii");  // Close connection on rejection
    }

    // Emit connection when request is accepted
    wsServer.handleUpgrade(request, socket, head, function done(ws) {
        wsServer.emit('connection', ws, request);
    });
});

Implementing the Client

With the server-side done, let’s move on to the client-side implementation. Start with the index.html file in the client folder:

<!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>WebSockets Chat</title>
</head>
<body>
    <h1>Hello WebSockets</h1>
    <div id="messages"></div>
    <input type="text" id="message">
    <button id="send">Send Message</button>
    <script src="script.js"></script>
</body>
</html>

Next, add the following code to the script.js file in the client folder:

// WebSocket variables
const url = "ws://localhost:9876/myWebsocket";
const mywsServer = new WebSocket(url);

// DOM Elements, 
const myMessages = document.getElementById("messages");
const myInput = document.getElementById("message");
const sendBtn = document.getElementById("send");

sendBtn.disabled = true;
sendBtn.addEventListener("click", sendMsg, false);

// Sending message from client
function sendMsg() {
    const text = myInput.value;
    msgGeneration(text, "Client");
    mywsServer.send(text);
}

// Displaying received messages in the browser
function msgGeneration(msg, from) {
    const newMessage = document.createElement("h5");
    newMessage.innerText = `${from} says: ${msg}`;
    myMessages.appendChild(newMessage);
}

// Enable the send button when connection is open
mywsServer.onopen = function() {
    sendBtn.disabled = false;
};

// Handle incoming messages
mywsServer.onmessage = function(event) {
    const { data } = event;
    msgGeneration(data, "Server");
};

WebSockets in Action

With the server and client implemented, you can now run your application. Open your HTML page, type a message in the input box, and click "Send Message"—the server will echo it back. For added fun, open the app in another browser or a different tab. Place both side by side, and you’ll see that messages sent from one instance will immediately appear in the other, demonstrating the power of WebSockets.

This simple chat application using WebSockets in Node.js showcases how easily you can create real-time applications. Feel free to get creative and expand on this foundation!

That’s it from my side! If this gets 200 likes, next blog will be a real time currency value checker!!! EXCITED??? hit the like button fs 👍

If you are having issues, do check out the git repo https://github.com/dipsubhro/Real-time-chat

44
Subscribe to my newsletter

Read articles from Subhradip Sinha directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Subhradip Sinha
Subhradip Sinha