How to Implement WebSockets in Node.js with Socket.io

This article provides a practical, step-by-step guide on how to implement real-time bi-directional communication in a Node.js application using the Socket.io library. You will learn how to set up a Node.js server, integrate Socket.io, establish connections, and handle events between the server and the client to build a functional real-time application.

Understanding WebSockets and Socket.io

WebSockets provide a persistent, low-latency connection between a client and a server, allowing both parties to send data at any time without the overhead of traditional HTTP polling.

While native WebSockets are supported by modern browsers, Socket.io is a popular library that builds on top of WebSockets. It offers additional reliability features like automatic reconnection, packet buffering, and fallback to HTTP long-polling if a WebSocket connection fails.


Step 1: Set Up Your Project

First, create a new directory for your project, initialize it, and install the necessary dependencies. You will need express to serve your files and socket.io for the WebSocket functionality.

mkdir node-socket-demo
cd node-socket-demo
npm init -y
npm install express socket.io

Step 2: Create the Node.js Server

Create a file named server.js in your root directory. In this file, you will set up an Express application, wrap it with Node’s native HTTP server, and initialize Socket.io on top of it.

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

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

// Serve the static HTML file
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'index.html'));
});

// Handle Socket.io connections
io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    // Listen for custom events from the client
    socket.on('chat message', (msg) => {
        console.log('Message received: ' + msg);
        // Broadcast the message to all connected clients
        io.emit('chat message', msg);
    });

    // Handle user disconnection
    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
    });
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});

Step 3: Create the Client-Side HTML

Next, create an index.html file in the same directory. This file will load the Socket.io client library (automatically served by the Socket.io server) and handle the user interface for sending and receiving messages.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Socket.io Real-Time App</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        #messages { list-style-type: none; padding: 0; }
        #messages li { padding: 8px; margin-bottom: 5px; background: #f4f4f4; border-radius: 4px; }
        #form { display: flex; gap: 10px; margin-top: 20px; }
        #input { flex-grow: 1; padding: 10px; }
        button { padding: 10px 20px; }
    </style>
</head>
<body>
    <h1>Real-Time Chat</h1>
    <ul id="messages"></ul>
    
    <form id="form" action="">
        <input id="input" autocomplete="off" placeholder="Type a message..." /><button>Send</button>
    </form>

    <!-- Include the Socket.io client script -->
    <script src="/socket.io/socket.io.js"></script>
    <script>
        // Initialize the socket connection
        const socket = io();

        const form = document.getElementById('form');
        const input = document.getElementById('input');
        const messages = document.getElementById('messages');

        // Send a message to the server on form submission
        form.addEventListener('submit', (e) => {
            e.preventDefault();
            if (input.value) {
                socket.emit('chat message', input.value);
                input.value = '';
            }
        });

        // Listen for message events from the server
        socket.on('chat message', (msg) => {
            const item = document.createElement('li');
            item.textContent = msg;
            messages.appendChild(item);
            window.scrollTo(0, document.body.scrollHeight);
        });
    </script>
</body>
</html>

Step 4: Run and Test the Application

Start your server using Node.js:

node server.js

Open your web browser and navigate to http://localhost:3000. To test the real-time functionality, open the same URL in a second, separate browser tab. When you type a message in one window and click “Send,” the message will instantly appear in both windows without reloading the page.