Day 1 of 5
⏱ ~60 minutes
WebSockets in 5 Days — Day 1

The WebSocket Protocol

HTTP polling vs WebSockets, the handshake, when to use real-time.

HTTP Polling vs WebSockets

Traditional web communication works on a request/response cycle: your browser asks, the server answers, and the connection closes. If you want new data, you have to ask again. This is HTTP polling — and for real-time features it's wasteful and slow.

WebSockets solve this by keeping the connection open. Once the initial handshake completes, both client and server can send messages at any time without the overhead of new HTTP connections. This is what powers chat apps, live dashboards, multiplayer games, and collaborative editors.

ℹ️
WebSocket vs HTTP at a glance: HTTP is like texting — you send a message and wait for a reply. WebSocket is like a phone call — both parties can speak at any moment once connected.

The WebSocket Handshake

WebSocket connections start with an HTTP upgrade request. The client sends a normal GET request with special headers: Upgrade: websocket and Connection: Upgrade. If the server supports WebSockets, it responds with status 101 Switching Protocols and the connection upgrades.

HTTP Upgrade Request
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

The ws Library — Native WebSockets in Node.js

The ws package is the lowest-level WebSocket library for Node.js. It's what Socket.io is built on top of. Understanding it first makes everything else clearer.

Node.js — Basic WebSocket Server
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
  console.log('Client connected');

  ws.on('message', (data) => {
    const message = data.toString();
    console.log('Received:', message);
    // Echo back to sender
    ws.send(`Server received: ${message}`);
  });

  ws.on('close', () => {
    console.log('Client disconnected');
  });

  // Send a welcome message immediately
  ws.send('Welcome! Connection established.');
});

console.log('WebSocket server running on ws://localhost:8080');

Ping/Pong — Keeping Connections Alive

WebSocket connections can silently drop without either party knowing. The WebSocket protocol has built-in ping/pong frames for heartbeats — the server periodically sends a ping, and the client must respond with a pong. If no pong arrives, the server knows the connection is dead.

Node.js — Heartbeat Implementation
const HEARTBEAT_INTERVAL = 30000; // 30 seconds

wss.on('connection', (ws) => {
  ws.isAlive = true;

  ws.on('pong', () => {
    ws.isAlive = true; // Reset on pong
  });
});

// Check all connections every 30 seconds
const interval = setInterval(() => {
  wss.clients.forEach((ws) => {
    if (!ws.isAlive) {
      return ws.terminate(); // Dead connection
    }
    ws.isAlive = false;
    ws.ping(); // Send ping
  });
}, HEARTBEAT_INTERVAL);
📝 Day 1 Exercise
Build Your First WebSocket Echo Server
  1. Run npm init -y && npm install ws in a new folder.
  2. Copy the basic server code above into server.js.
  3. Open your browser's developer console on any page and paste: const ws = new WebSocket('ws://localhost:8080'); ws.onmessage = e => console.log(e.data);
  4. Send a message: ws.send('Hello WebSocket!');
  5. Add the heartbeat code and verify the connection stays alive.
  6. Open two browser tabs and try to figure out how to broadcast a message to all connected clients.

Day 1 Summary

  • WebSockets maintain a persistent connection; HTTP closes after each response.
  • The handshake starts as HTTP and upgrades to the WebSocket protocol with status 101.
  • The ws library gives you raw WebSocket access in Node.js.
  • Implement ping/pong heartbeats to detect dead connections.
Finished this lesson?