Debugging & Troubleshooting

Debugging WebSocket Disconnections

How to diagnose WebSocket disconnections using close codes, heartbeat analysis, proxy timeouts, and browser DevTools.

WebSocket Close Codes Explained

When a WebSocket connection closes, both sides exchange a close frame containing a numeric status code and an optional reason string. These codes are your first diagnostic signal:

CodeNameCommon Cause
`1000`Normal ClosureIntentional close by either party
`1001`Going AwayPage navigation, server restart
`1006`Abnormal ClosureTCP closed without close frame (network drop)
`1007`Invalid FrameMalformed UTF-8 in text frame
`1008`Policy ViolationAuth failure, rate limit exceeded
`1009`Message Too BigFrame exceeds server's max size
`1011`Internal ErrorUnhandled server exception
`1012`Service RestartServer-initiated rolling restart
`1013`Try Again LaterServer temporarily overloaded

Code 1006 is the most common in production and the hardest to debug — it means the TCP connection closed without a proper WebSocket close handshake, often due to a proxy or firewall timeout.

Common Disconnect Causes

Proxy idle timeout: Nginx, AWS ALB, and Cloudflare all have default idle timeouts (Nginx: 60s, AWS ALB: 60s, Cloudflare: 100s). If no data is sent in that window, the proxy closes the TCP connection — the WebSocket layer sees this as a 1006 abnormal closure.

Server process restart: a rolling deploy or crash closes all active WebSocket connections, producing 1001 or 1006.

Client sleep/hibernate: mobile devices suspend network activity. When the device wakes, the server-side socket may have been reaped.

Memory pressure: if the server runs out of memory, processes are killed and connections closed abruptly (1006).

Ping/Pong and Heartbeats

The WebSocket protocol defines ping and pong control frames (RFC 6455 section 5.5). A server sends a ping frame; the client must respond with a pong frame. This:

  • Proves the connection is still alive
  • Resets the proxy idle timeout
  • Allows detection of half-open connections
# Server-side heartbeat (websockets library)
import asyncio, websockets

async def handler(websocket):
    async for message in websocket:
        await websocket.send(message)

async def main():
    async with websockets.serve(
        handler, 'localhost', 8765,
        ping_interval=20,   # send ping every 20s
        ping_timeout=10,    # close if no pong within 10s
    ):
        await asyncio.Future()

Set ping_interval to roughly half the shortest proxy timeout in your stack. For a 60s ALB timeout, use ping_interval=25.

Proxy and Load Balancer Timeouts

Nginx:

location /ws/ {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_read_timeout 3600s;   # 1 hour
    proxy_send_timeout 3600s;
}

AWS ALB: increase idle timeout under Load Balancer Attributes to a value larger than your heartbeat interval.

Cloudflare: WebSocket connections are supported on all plans, with a 100-second idle timeout. Use heartbeats shorter than 100 seconds.

Reconnection Strategies

Clients should always implement automatic reconnection:

function createWebSocket(url) {
  let ws;
  let reconnectDelay = 1000;

  function connect() {
    ws = new WebSocket(url);
    ws.onopen = () => { reconnectDelay = 1000; };
    ws.onclose = (event) => {
      if (event.code !== 1000) {
        setTimeout(connect, reconnectDelay);
        reconnectDelay = Math.min(reconnectDelay * 2, 30000);
      }
    };
  }
  connect();
  return { send: (msg) => ws.send(msg) };
}

Browser DevTools for WebSocket

In Chrome: DevTools → Network tab → filter by WS. Click a WebSocket connection to see:

  • Headers — upgrade handshake, Sec-WebSocket-Key
  • Messages — all frames with timestamps and direction (↑ sent, ↓ received)
  • Close code — visible when the connection closes

Monitoring WebSocket Health

Track these metrics in production:

  • Active connection count
  • Disconnect rate per close code (1006 spikes indicate proxy issues)
  • Message latency (ping round-trip time)
  • Reconnection rate (high rate suggests persistent instability)

相关协议

相关术语表条目

更多内容: Debugging & Troubleshooting