How To Build Real-Time Apps with Node.js and Socket.io

2 minute read


“Real-Time Apps with Node.js and Socket.io”


Introduction to Real-Time Communication

Real-time applications allow instant data exchange between clients and servers, enabling live interactions like chat apps, live notifications, and collaborative tools. Traditional HTTP (request-response) is inefficient for real-time use cases because it requires constant polling. WebSockets solve this by providing a persistent, bidirectional communication channel.

Why Socket.io?

  • Abstraction Layer: Simplifies WebSocket implementation with fallback options (e.g., long polling).
  • Cross-Platform: Works with browsers, mobile apps, and IoT devices.
  • Rooms and Namespaces: Organize clients into groups for targeted messaging.

Prerequisites

  • Node.js and npm installed.
  • Basic knowledge of Express.js.

Step 1: Setting Up a Socket.io Server

  1. Create a project directory and initialize npm:
    mkdir realtime-app && cd realtime-app  
    npm init -y  
    
  2. Install dependencies:
    npm install express socket.io  
    
  3. Create app.js with Express and Socket.io:
    const express = require('express');
    const http = require('http');
    const { Server } = require('socket.io');
    
    const app = express();
    const server = http.createServer(app);
    const io = new Server(server);
    
    // Serve static files (HTML/CSS/JS)
    app.use(express.static('public'));
    
    // Socket.io connection handler
    io.on('connection', (socket) => {
      console.log('A user connected:', socket.id);
    
      socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
      });
    });
    
    const PORT = 3000;
    server.listen(PORT, () => {
      console.log(`Server running on http://localhost:${PORT}`);
    });
    

Step 2: Building a Chat Application Frontend

  1. Create a public folder and add index.html:
    <!DOCTYPE html>
    <html>
      <head>
        <title>Socket.io Chat</title>
      </head>
      <body>
        <ul id="messages"></ul>
        <form id="message-form">
          <input id="message-input" autocomplete="off" />
          <button>Send</button>
        </form>
        <script src="/socket.io/socket.io.js"></script>
        <script>
          const socket = io();
          const form = document.getElementById('message-form');
          const input = document.getElementById('message-input');
          const messages = document.getElementById('messages');
    
          form.addEventListener('submit', (e) => {
            e.preventDefault();
            if (input.value) {
              socket.emit('chat message', input.value);
              input.value = '';
            }
          });
    
          socket.on('chat message', (msg) => {
            const li = document.createElement('li');
            li.textContent = msg;
            messages.appendChild(li);
          });
        </script>
      </body>
    </html>
    
  2. Run the server:
    node app.js
    
  3. Open http://localhost:3000 in multiple browsers to test real-time messaging.

Step 3: Advanced Features

Broadcasting Messages

  • Send messages to all clients except the sender:
    socket.on('chat message', (msg) => {
      socket.broadcast.emit('chat message', msg);
    });
    

Rooms

  • Assign users to rooms (e.g., support channels):
    socket.on('join room', (room) => {
      socket.join(room);
      io.to(room).emit('user joined', socket.id);
    });
    

User Presence

  • Track online users:
    let users = [];
    
    io.on('connection', (socket) => {
      users.push(socket.id);
      io.emit('user count', users.length);
    
      socket.on('disconnect', () => {
        users = users.filter(id => id !== socket.id);
        io.emit('user count', users.length);
      });
    });
    

Step 4: Handling Reconnections and Failures

Socket.io automatically handles reconnections. Customize retry logic:

const io = new Server(server, {
  pingTimeout: 60000,  // Wait 60s before closing idle connections
  cors: { origin: '*' } // Allow cross-origin requests
});

Step 5: Scaling with Redis Adapter

For horizontal scaling across multiple servers:

  1. Install the Redis adapter:
    npm install @socket.io/redis-adapter redis
    
  2. Configure in app.js:
    const { createClient } = require('redis');
    const { createAdapter } = require('@socket.io/redis-adapter');
    
    const pubClient = createClient({ host: 'localhost', port: 6379 });
    const subClient = pubClient.duplicate();
    
    io.adapter(createAdapter(pubClient, subClient));
    

Conclusion

You’ve built a real-time chat app with Socket.io! Next steps:

  • Add user nicknames and typing indicators.
  • Integrate with databases for message history.
  • Explore Socket.io’s binary data support for gaming apps.

Leave a comment