Beginner
15 min
Full Guide

Introduction to Real-Time Web

Understand real-time communication on the web, its importance, and different technologies available

What is Real-Time Communication?

Real-time communication enables instant data exchange between clients and servers (or directly between clients) without the traditional request-response delay. Instead of users manually refreshing pages, updates appear instantly—like magic.

Think about your favorite apps: chat messages appearing instantly, stock prices updating live, multiplayer games synchronizing player positions, or collaborative documents showing other users' cursors in real-time. All of these rely on real-time web technologies.

🎯 Real-Time Use Cases

Communication

  • • Chat applications (Slack, Discord)
  • • Video conferencing (Zoom, Google Meet)
  • • Notifications and alerts

Collaboration

  • • Document editing (Google Docs, Figma)
  • • Whiteboarding tools
  • • Multiplayer games

Live Data

  • • Stock tickers and trading
  • • Sports scores and live events
  • • IoT dashboards

Social

  • • Live streaming (Twitch, YouTube Live)
  • • Social feeds and reactions
  • • Presence indicators (online/typing)

The Evolution: From Polling to Push

Understanding how we got to modern real-time is crucial. Let's trace the evolution:

1. Traditional HTTP Request-Response

// The classic model - client always initiates
// User clicks "Refresh" or waits for page reload
fetch('/api/messages')
  .then(res => res.json())
  .then(messages => updateUI(messages));

// Problem: No way for server to notify client of new data!

In traditional HTTP, the client must always initiate communication. The server cannot "push" data to the client—it can only respond to requests.

2. Short Polling

// Short polling - repeatedly ask "anything new?"
function pollForUpdates() {
  setInterval(async () => {
    const response = await fetch('/api/messages?since=' + lastTimestamp);
    const newMessages = await response.json();
    
    if (newMessages.length > 0) {
      lastTimestamp = newMessages[newMessages.length - 1].timestamp;
      displayMessages(newMessages);
    }
  }, 3000); // Check every 3 seconds
}

// Problems:
// - Wastes bandwidth (mostly empty responses)
// - Wastes server resources (constant requests)
// - Not truly real-time (up to 3 second delay)
// - Battery drain on mobile devices

3. Long Polling

// Long polling - "hold my request until you have something"
async function longPoll() {
  while (true) {
    try {
      // This request stays open until server has new data
      // or timeout occurs (usually 30-60 seconds)
      const response = await fetch('/api/messages/subscribe', {
        timeout: 60000
      });
      
      const messages = await response.json();
      displayMessages(messages);
      
    } catch (error) {
      // Reconnect on error or timeout
      await sleep(1000);
    }
  }
}

// Better than short polling:
// ✓ Near real-time updates
// ✓ Less wasted requests
// 
// Still has issues:
// ✗ Each message requires new HTTP connection
// ✗ HTTP overhead on every response
// ✗ Complex server implementation

4. Server-Sent Events (SSE)

// SSE - server can push text data to client
const eventSource = new EventSource('/api/events');

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  displayMessage(data);
};

eventSource.onerror = (error) => {
  console.error('SSE error:', error);
  // EventSource auto-reconnects!
};

// Advantages:
// ✓ Simple API (built into browsers)
// ✓ Automatic reconnection
// ✓ Works over HTTP/2
// 
// Limitations:
// ✗ One-way only (server → client)
// ✗ Text-based (no binary)
// ✗ Limited browser connections per domain

5. WebSockets

// WebSocket - full-duplex, persistent connection
const socket = new WebSocket('wss://api.example.com/ws');

socket.onopen = () => {
  console.log('Connected!');
  socket.send(JSON.stringify({ type: 'subscribe', channel: 'chat' }));
};

socket.onmessage = (event) => {
  const message = JSON.parse(event.data);
  displayMessage(message);
};

// Send messages anytime!
function sendMessage(text) {
  socket.send(JSON.stringify({ type: 'message', text }));
}

// Advantages:
// ✓ Full duplex (bidirectional)
// ✓ Low latency (no HTTP overhead per message)
// ✓ Binary and text support
// ✓ Efficient for high-frequency updates

6. WebRTC

// WebRTC - peer-to-peer, no server in the middle!
const peerConnection = new RTCPeerConnection(config);

// Get local video/audio
const stream = await navigator.mediaDevices.getUserMedia({ 
  video: true, 
  audio: true 
});

// Add tracks to peer connection
stream.getTracks().forEach(track => {
  peerConnection.addTrack(track, stream);
});

// Listen for remote tracks
peerConnection.ontrack = (event) => {
  remoteVideo.srcObject = event.streams[0];
};

// Advantages:
// ✓ Direct peer-to-peer (lowest possible latency)
// ✓ No server bandwidth for media
// ✓ Video, audio, and arbitrary data
// 
// Complexity:
// ✗ Requires signaling server for connection setup
// ✗ NAT traversal challenges
// ✗ More complex API

Technology Comparison

Technology Direction Protocol Best For
Polling Client → Server HTTP Legacy systems, simple updates
Long Polling Server → Client HTTP Fallback, behind proxies
SSE Server → Client HTTP News feeds, notifications
WebSocket Bidirectional WS/WSS Chat, gaming, collaboration
WebRTC Peer-to-Peer UDP/SCTP Video calls, file sharing

Choosing the Right Technology

// Decision tree for real-time technology choice:

function chooseRealtimeTech(requirements) {
  // Need peer-to-peer media/video?
  if (requirements.peerToPeer || requirements.videoStreaming) {
    return 'WebRTC';
  }
  
  // Need bidirectional communication?
  if (requirements.clientToServer && requirements.serverToClient) {
    // High frequency updates or gaming?
    if (requirements.highFrequency || requirements.gaming) {
      return 'WebSocket';
    }
    // Moderate updates with fallback needs?
    return 'Socket.io'; // Handles fallbacks automatically
  }
  
  // Only server → client updates?
  if (requirements.serverToClient) {
    // Simple notifications/feeds?
    if (requirements.simple && !requirements.binary) {
      return 'SSE'; // Simplest API, auto-reconnect
    }
    return 'WebSocket';
  }
  
  // Infrequent updates, simplicity preferred?
  if (requirements.infrequent) {
    return 'Long Polling';
  }
  
  return 'WebSocket'; // Safe default
}

⚠️ Real-Time Challenges

Connection Management

  • • Handling disconnections gracefully
  • • Reconnection with exponential backoff
  • • State synchronization after reconnect

Scaling

  • • Each connection consumes server memory
  • • Broadcasting across multiple servers
  • • Connection limits per server

Security

  • • Authentication for persistent connections
  • • Rate limiting messages
  • • Validating all incoming data

Network Issues

  • • NAT traversal (especially WebRTC)
  • • Firewall and proxy restrictions
  • • Mobile network switching

💡 What You'll Learn in This Course

  • WebSocket Protocol - Deep dive into handshake, frames, and lifecycle
  • Building Servers - Create WebSocket servers in Node.js
  • Socket.io - Use the most popular real-time library
  • Server-Sent Events - Simple one-way streaming
  • WebRTC Architecture - Understand peer-to-peer connections
  • Signaling Servers - Connect peers across the internet
  • Video Streaming - Build video call applications
  • Design Patterns - Scale real-time applications