Back to blog
InspectionJanuary 1, 2024· 6 min read

WebSocket Connections: Analyzing Real-Time Web Communication

A practical Fusebox guide to websocket connections.

WebSocket Connections: Analyzing Real-Time Web Communication

Published: January 2024
Reading time: 7 minutes

WebSockets power real-time features like chat, notifications, live updates, and collaborative editing. Here's how to detect, analyze, and understand WebSocket connections on any website.

What Are WebSockets?

Unlike regular HTTP requests (request → response → done), WebSockets create persistent, two-way connections:

HTTP: Client → Server → Response → Connection Closed
WebSocket: Client ↔ Server (continuous bidirectional communication)

This enables:

  • Live chat messages
  • Real-time notifications
  • Stock price updates
  • Collaborative editing
  • Live sports scores
  • Multiplayer games

Detecting WebSocket Connections

1. Browser DevTools Method

// In Chrome DevTools:
// 1. Network tab
// 2. Filter: WS
// 3. Look for 101 Switching Protocols

// Or programmatically:
const sockets = [];
const originalWebSocket = window.WebSocket;

window.WebSocket = function(...args) {
  const socket = new originalWebSocket(...args);
  sockets.push({
    url: args[0],
    protocols: args[1],
    socket: socket,
    created: new Date()
  });
  
  console.log('WebSocket created:', args[0]);
  
  // Monitor events
  socket.addEventListener('open', () => {
    console.log('WebSocket opened:', args[0]);
  });
  
  socket.addEventListener('message', (event) => {
    console.log('WebSocket message:', event.data);
  });
  
  socket.addEventListener('close', () => {
    console.log('WebSocket closed:', args[0]);
  });
  
  return socket;
};

2. Performance API Detection

// Find WebSocket upgrade requests
performance.getEntriesByType('resource').forEach(entry => {
  if (entry.name.startsWith('ws://') || entry.name.startsWith('wss://')) {
    console.log('WebSocket connection:', entry.name);
  }
});

3. Common WebSocket Patterns

// Socket.io
wss://example.com/socket.io/?transport=websocket

// SignalR
wss://example.com/signalr/connect

// Raw WebSocket
wss://example.com/ws
wss://example.com/realtime

// GraphQL Subscriptions
wss://example.com/graphql-ws

Real-World WebSocket Examples

Example 1: Chat Application

Connection detected:

URL: wss://chat.example.com/socket.io/?userId=123&token=abc
Protocol: socket.io

Messages observed:
→ {"type":"auth","token":"abc123"}
← {"type":"auth_success","userId":"123"}
→ {"type":"join_room","room":"general"}
← {"type":"room_joined","users":45}
← {"type":"message","user":"John","text":"Hello!","timestamp":1234567890}
→ {"type":"message","text":"Hi there!"}
← {"type":"message_sent","id":"msg_789"}

What this reveals:

  • Using Socket.io (popular library)
  • Token-based authentication
  • Room-based chat system
  • 45 users in room
  • Message acknowledgment pattern

Example 2: Trading Platform

Multiple WebSocket connections:

// Price feed
wss://stream.exchange.com/quotes?symbols=BTC,ETH,DOGE

// Order updates
wss://api.exchange.com/orders/stream

// News feed
wss://news.exchange.com/realtime

Message frequency analysis:

Price updates: 10-50 messages/second
Order updates: 1-5 messages/minute
News updates: 1-2 messages/minute

Total bandwidth: ~100KB/second

Example 3: Collaborative Editor

WebSocket for Google Docs-style editing:

URL: wss://collab.app.com/doc/abc123
Protocol: ["v1.collab"]

Message types:
{
  "type": "cursor",
  "userId": "user456",
  "position": {"line": 10, "ch": 45}
}

{
  "type": "operation",
  "op": ["retain", 100, "insert", "Hello", "retain", 50],
  "revision": 234
}

{
  "type": "presence",
  "users": [
    {"id": "123", "name": "Alice", "color": "#ff0000"},
    {"id": "456", "name": "Bob", "color": "#00ff00"}
  ]
}

WebSocket Security Analysis

1. Authentication Methods

Token in URL (Common but risky):

wss://api.example.com/ws?token=secret123
// Token visible in logs, history

Token in protocol (Better):

new WebSocket('wss://api.example.com/ws', ['auth-secret123']);

Post-connection auth (Best):

const ws = new WebSocket('wss://api.example.com/ws');
ws.onopen = () => {
  ws.send(JSON.stringify({
    type: 'auth',
    token: localStorage.getItem('authToken')
  }));
};

2. Common Security Issues

Missing encryption:

// Bad: Unencrypted
ws://api.example.com/chat

// Good: Encrypted
wss://api.example.com/chat

No origin validation:

// Server should check Origin header
Origin: https://evil-site.com

// Prevent cross-site WebSocket hijacking

Missing rate limiting:

// Flooding attack possible
for (let i = 0; i < 10000; i++) {
  ws.send('spam message ' + i);
}

Performance Analysis

1. Message Frequency Monitor

function monitorWebSocketPerformance(url) {
  const ws = new WebSocket(url);
  const stats = {
    messagesReceived: 0,
    bytesSent: 0,
    bytesReceived: 0,
    startTime: Date.now(),
    messageLog: []
  };
  
  ws.onmessage = (event) => {
    stats.messagesReceived++;
    stats.bytesReceived += event.data.length;
    
    // Log message rate
    const elapsed = (Date.now() - stats.startTime) / 1000;
    const rate = stats.messagesReceived / elapsed;
    
    stats.messageLog.push({
      time: Date.now(),
      size: event.data.length,
      rate: rate.toFixed(2)
    });
    
    // Alert if too frequent
    if (rate > 100) {
      console.warn('High message rate:', rate, 'msg/sec');
    }
  };
  
  // Override send to track outgoing
  const originalSend = ws.send;
  ws.send = function(data) {
    stats.bytesSent += data.length || 0;
    return originalSend.call(this, data);
  };
  
  return stats;
}

2. Connection Health Check

class WebSocketHealthMonitor {
  constructor(ws) {
    this.ws = ws;
    this.pingInterval = null;
    this.lastPong = Date.now();
    
    this.startHealthCheck();
  }
  
  startHealthCheck() {
    // Send ping every 30 seconds
    this.pingInterval = setInterval(() => {
      if (this.ws.readyState === WebSocket.OPEN) {
        this.ws.send(JSON.stringify({ type: 'ping' }));
        
        // Check if pong received
        setTimeout(() => {
          if (Date.now() - this.lastPong > 35000) {
            console.error('WebSocket unhealthy - no pong received');
            this.ws.close();
          }
        }, 5000);
      }
    }, 30000);
    
    // Listen for pongs
    this.ws.addEventListener('message', (event) => {
      const data = JSON.parse(event.data);
      if (data.type === 'pong') {
        this.lastPong = Date.now();
      }
    });
  }
}

Common WebSocket Libraries

1. Socket.io Detection

// Socket.io signs
if (window.io) {
  console.log('Socket.io detected');
  
  // Monitor connections
  const sockets = io.sockets;
  console.log('Active sockets:', Object.keys(sockets).length);
}

// URL pattern
// wss://example.com/socket.io/?EIO=4&transport=websocket

2. SignalR Detection

// SignalR signs
if (window.$ && $.signalR) {
  console.log('SignalR detected');
  
  // Get active connections
  const connections = $.signalR.connections;
}

// Or for newer versions
if (window.signalR) {
  console.log('SignalR Core detected');
}

3. Native WebSocket

// No library wrapper
const ws = new WebSocket('wss://example.com/ws');
// Direct protocol usage

Debugging WebSocket Issues

1. Connection Problems

const ws = new WebSocket('wss://example.com/ws');

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

ws.onclose = (event) => {
  console.log('WebSocket closed:', {
    code: event.code,
    reason: event.reason,
    wasClean: event.wasClean
  });
  
  // Common close codes
  switch(event.code) {
    case 1000: console.log('Normal closure'); break;
    case 1001: console.log('Going away'); break;
    case 1006: console.log('Abnormal closure'); break;
    case 1009: console.log('Message too big'); break;
    case 1011: console.log('Server error'); break;
  }
};

2. Message Debugging

// Log all WebSocket traffic
function debugWebSocket(url) {
  const ws = new WebSocket(url);
  
  // Log lifecycle
  ws.onopen = () => console.log('🟢 Connected');
  ws.onclose = (e) => console.log('🔴 Disconnected:', e.code);
  ws.onerror = (e) => console.log('⚠️ Error:', e);
  
  // Log messages with formatting
  ws.onmessage = (event) => {
    try {
      const data = JSON.parse(event.data);
      console.log('📥 Received:', data);
    } catch {
      console.log('📥 Received (raw):', event.data);
    }
  };
  
  // Override send to log outgoing
  const originalSend = ws.send.bind(ws);
  ws.send = (data) => {
    try {
      const parsed = JSON.parse(data);
      console.log('📤 Sending:', parsed);
    } catch {
      console.log('📤 Sending (raw):', data);
    }
    return originalSend(data);
  };
  
  return ws;
}

WebSocket Best Practices

1. Reconnection Logic

class ReconnectingWebSocket {
  constructor(url, options = {}) {
    this.url = url;
    this.reconnectDelay = options.reconnectDelay || 1000;
    this.maxReconnectDelay = options.maxReconnectDelay || 30000;
    this.reconnectAttempts = 0;
    
    this.connect();
  }
  
  connect() {
    this.ws = new WebSocket(this.url);
    
    this.ws.onopen = () => {
      console.log('Connected');
      this.reconnectAttempts = 0;
      this.reconnectDelay = 1000;
    };
    
    this.ws.onclose = () => {
      console.log('Disconnected, reconnecting...');
      this.scheduleReconnect();
    };
  }
  
  scheduleReconnect() {
    setTimeout(() => {
      this.reconnectAttempts++;
      this.connect();
    }, Math.min(this.reconnectDelay * Math.pow(2, this.reconnectAttempts), 
                this.maxReconnectDelay));
  }
}

2. Message Queuing

class QueuedWebSocket {
  constructor(url) {
    this.url = url;
    this.messageQueue = [];
    this.connected = false;
    
    this.connect();
  }
  
  connect() {
    this.ws = new WebSocket(this.url);
    
    this.ws.onopen = () => {
      this.connected = true;
      this.flushQueue();
    };
    
    this.ws.onclose = () => {
      this.connected = false;
    };
  }
  
  send(data) {
    if (this.connected && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(data);
    } else {
      this.messageQueue.push(data);
    }
  }
  
  flushQueue() {
    while (this.messageQueue.length > 0) {
      const message = this.messageQueue.shift();
      this.ws.send(message);
    }
  }
}

Quick WebSocket Audit

// Run this to analyze WebSockets on current page
(function auditWebSockets() {
  console.log('🔍 WebSocket Audit');
  
  // Check for WebSocket support
  if (!window.WebSocket) {
    console.log('❌ WebSockets not supported');
    return;
  }
  
  // Check for libraries
  const libraries = [];
  if (window.io) libraries.push('Socket.io');
  if (window.Primus) libraries.push('Primus');
  if (window.SockJS) libraries.push('SockJS');
  if (window.signalR || (window.$ && $.signalR)) libraries.push('SignalR');
  
  if (libraries.length) {
    console.log('📚 Libraries found:', libraries.join(', '));
  }
  
  // Monitor new connections
  let connectionCount = 0;
  const originalWS = window.WebSocket;
  
  window.WebSocket = function(...args) {
    connectionCount++;
    console.log(`🔌 WebSocket #${connectionCount}:`, args[0]);
    
    const ws = new originalWS(...args);
    
    // Monitor this connection
    ws.addEventListener('open', () => {
      console.log(`✅ WebSocket #${connectionCount} opened`);
    });
    
    let messageCount = 0;
    ws.addEventListener('message', () => {
      messageCount++;
      if (messageCount % 100 === 0) {
        console.log(`📊 WebSocket #${connectionCount}: ${messageCount} messages`);
      }
    });
    
    return ws;
  };
  
  console.log('✅ WebSocket monitoring active');
})();

The Bottom Line

WebSockets reveal:

  • Real-time features of the application
  • Architecture patterns (polling vs. push)
  • Scale considerations (message frequency)
  • Security implementation (auth, encryption)
  • Third-party integrations (chat, analytics)

Understanding WebSockets helps you build better real-time features and debug connection issues.


Monitor WebSocket connections instantly: Fusebox tracks all WebSocket connections, messages, and performance metrics while you browse. See real-time communication in action. $29 one-time purchase.