Summary
The VPZONE integration closes and reopens its chat WebSocket roughly every 25 seconds, indefinitely, on a channel that is live and has viewers. Each cycle completes a full handshake and re-downloads the entire history replay.
I maintain VPZONE, so I was able to instrument the server side. The server never closes these connections — the close is initiated by AxelChat. Details below so you don't have to chase the server end.
Observed
Close timestamps for one AxelChat instance on one channel (server access log, UTC):
22:50:35 22:51:00 22:51:25 22:52:05 22:52:30 22:53:10
22:57:50 22:58:15 22:58:40 22:59:05
Every entry is GET /ws?channel=<slug> -> 101 with ~41 KB transferred: the upgrade succeeds and the full history replay is delivered each time before the socket goes away.
The requests carry Chrome/148.0.0.0 (the embedded Chromium), not the AxelChat/1.0 UA used elsewhere — that is how I attributed them.
Evidence the server is not the cause
| Check |
Result |
nginx proxy_read_timeout on that vhost |
86400 (24 h), no proxy timeout |
| Server-initiated close in that window |
none |
Node ws client, anonymous, foreign Origin, same URL |
stays connected 5+ minutes, receives 9 protocol pings |
| A normal Chrome tab on our site |
0 reconnects in 3 minutes |
I also changed the two plausible server-side causes and redeployed:
- Application-level keepalive
30s -> 15s (a client that cannot observe protocol ping/pong has only this to go on).
- The server used to answer a non-
msg frame from an anonymous socket with an error / auth_required frame instead of ignoring it, contrary to our own documented contract. Now silently ignored.
Neither changed the interval. It stayed at 25 s, which points to a fixed client-side timer rather than starvation or an error-handling path.
Endpoint
wss://chat.vpzone.tv/ws?channel=<slug> (anonymous; token optional)
- No Origin allowlist;
null and chrome-extension:// origins are accepted.
- Server sends a protocol
ping every 30 s and an application presence frame every 15 s.
- Close codes:
1008 bad slug or banned, 1013 per-IP rate limit, 1001 ping timeout.
- Contract: https://vpzone.tv/api/docs (Realtime tag).
Impact
At 25 s that is about 144 reconnects per hour, each replaying ~41 KB of history and costing one history query on our side: roughly 5.9 MB/hour per AxelChat viewer, and the viewer count flaps.
What would help
If there is a fixed reconnect or idle timer in the VPZONE service, resetting it on any received frame (including presence) should be enough. Happy to run an instrumented build against production and send logs, or to add anything to the server side that would make this easier.
Summary
The VPZONE integration closes and reopens its chat WebSocket roughly every 25 seconds, indefinitely, on a channel that is live and has viewers. Each cycle completes a full handshake and re-downloads the entire history replay.
I maintain VPZONE, so I was able to instrument the server side. The server never closes these connections — the close is initiated by AxelChat. Details below so you don't have to chase the server end.
Observed
Close timestamps for one AxelChat instance on one channel (server access log, UTC):
Every entry is
GET /ws?channel=<slug>->101with ~41 KB transferred: the upgrade succeeds and the full history replay is delivered each time before the socket goes away.The requests carry
Chrome/148.0.0.0(the embedded Chromium), not theAxelChat/1.0UA used elsewhere — that is how I attributed them.Evidence the server is not the cause
proxy_read_timeouton that vhost86400(24 h), no proxy timeoutwsclient, anonymous, foreignOrigin, same URLI also changed the two plausible server-side causes and redeployed:
30s -> 15s(a client that cannot observe protocol ping/pong has only this to go on).msgframe from an anonymous socket with anerror / auth_requiredframe instead of ignoring it, contrary to our own documented contract. Now silently ignored.Neither changed the interval. It stayed at 25 s, which points to a fixed client-side timer rather than starvation or an error-handling path.
Endpoint
nullandchrome-extension://origins are accepted.pingevery 30 s and an applicationpresenceframe every 15 s.1008bad slug or banned,1013per-IP rate limit,1001ping timeout.Impact
At 25 s that is about 144 reconnects per hour, each replaying ~41 KB of history and costing one history query on our side: roughly 5.9 MB/hour per AxelChat viewer, and the viewer count flaps.
What would help
If there is a fixed reconnect or idle timer in the VPZONE service, resetting it on any received frame (including
presence) should be enough. Happy to run an instrumented build against production and send logs, or to add anything to the server side that would make this easier.