Lab 08: WebSockets & Real-Time

Time: 30 minutes | Level: Advanced | Docker: docker run -it --rm node:20-alpine sh

Overview

Build real-time applications with the ws module: broadcasting, rooms/namespaces, heartbeat/ping-pong, reconnection logic, and message queuing for disconnected clients.


Step 1: Setup

cd /tmp && npm init -y --quiet
npm install ws

Step 2: Basic WebSocket Server & Client

const WebSocket = require('ws');

// Server
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws, req) => {
  const clientId = Math.random().toString(36).slice(2, 9);
  ws.clientId = clientId;
  console.log(`Client connected: ${clientId}`);

  // Send welcome message
  ws.send(JSON.stringify({ type: 'WELCOME', clientId }));

  ws.on('message', (data, isBinary) => {
    try {
      const message = JSON.parse(data.toString());
      console.log(`Message from ${clientId}:`, message);

      // Echo back
      ws.send(JSON.stringify({ type: 'ECHO', original: message, clientId }));
    } catch {
      ws.send(JSON.stringify({ type: 'ERROR', message: 'Invalid JSON' }));
    }
  });

  ws.on('close', (code, reason) => {
    console.log(`Client disconnected: ${clientId} (${code})`);
  });

  ws.on('error', (err) => {
    console.error(`Error from ${clientId}:`, err.message);
  });
});

// Client
const ws = new WebSocket('ws://localhost:8080');

ws.on('open', () => {
  console.log('Connected to server');
  ws.send(JSON.stringify({ type: 'HELLO', message: 'Hi from client!' }));
});

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());
  console.log('Received:', msg);
  if (msg.type === 'ECHO') ws.close();
});

Step 3: Broadcasting


Step 4: Rooms (Namespaces)


Step 5: Heartbeat / Ping-Pong


Step 6: Reconnection Logic (Client Side)


Step 7: Message Queue for Offline Clients


Step 8: Capstone — WebSocket Server + Client Demo

📸 Verified Output:


Summary

Feature
API
Notes

Server

new WebSocket.Server({ port })

Listens for connections

Client

new WebSocket(url)

Connects to server

Send

ws.send(string/Buffer)

Send message

Broadcast

Loop wss.clients

No built-in broadcast

Rooms

Custom Map<roomId, Set<ws>>

Group clients

Heartbeat

ws.ping() + ws.on('pong')

Detect dead connections

Reconnect

Custom ReconnectingWebSocket

Exponential backoff

Message queue

Custom queue

Buffer offline messages

Close codes

ws.close(code, reason)

1000=normal, 1001=going away

Last updated