All posts

How to Debug WebSocket Disconnections

Diagnose WebSocket disconnection issues with close code analysis, heartbeat implementation, proxy configuration, and reconnection strategies.

How to Debug WebSocket Disconnections

WebSocket connections drop for many reasons. Here's how to systematically identify why.

Step 1: Check Close Codes

WebSocket close events include a code and reason:

ws.addEventListener('close', (event) => {
  console.log(`WebSocket closed: code=${event.code} reason=${event.reason}`);
});

Common close codes:

  • 1000 — Normal closure (intentional)
  • 1001 — Server going away (deployment/restart)
  • 1006 — Abnormal closure (no close frame; usually network issue)
  • 1008 — Policy violation
  • 1011 — Server encountered unexpected condition

Step 2: Implement Heartbeats

Silent disconnections happen when the TCP connection dies without a close frame. Use ping/pong:

// Client-side heartbeat
function startHeartbeat(ws) {
  const interval = setInterval(() => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({ type: 'ping' }));
    }
  }, 30000);

  ws.addEventListener('close', () => clearInterval(interval));
}
# Server-side (Python websockets)
async def handler(websocket):
    try:
        async for message in websocket:
            data = json.loads(message)
            if data.get('type') == 'ping':
                await websocket.send(json.dumps({'type': 'pong'}))
    except websockets.ConnectionClosed as e:
        logger.info(f"Connection closed: {e.code} {e.reason}")

Step 3: Check Infrastructure

Proxies and load balancers commonly cause disconnections:

  • Nginx — default proxy_read_timeout is 60s; increase for WebSocket:

```nginx

proxy_read_timeout 3600s;

proxy_send_timeout 3600s;

```

  • AWS ALB — idle timeout default is 60s; increase in target group settings
  • Cloudflare — 100s idle timeout (not configurable on free plans)

Step 4: Implement Reconnection

function connectWithRetry(url, maxRetries = 5) {
  let retries = 0;
  function connect() {
    const ws = new WebSocket(url);
    ws.onclose = (event) => {
      if (event.code !== 1000 && retries < maxRetries) {
        const delay = Math.min(1000 * Math.pow(2, retries), 30000);
        retries++;
        setTimeout(connect, delay);
      }
    };
    ws.onopen = () => { retries = 0; };
    return ws;
  }
  return connect();
}

Track WebSocket errors in Bugsly to identify patterns — if disconnections spike during deployments, you need better connection draining. If they spike at specific times, check load patterns or cron jobs affecting your server.

Try Bugsly Free

AI-powered error tracking that explains your bugs. Set up in 2 minutes, free forever for small projects.

Get Started Free