A WebSocket drops when the board stops servicing it. Remove blocking delays and keep messages small.
What the message means
The connection needs regular attention from the code. Long delays, large frames or a flood of messages make the peer time out.
Fix it in this order
- Remove long delay() calls and use timers instead.
- Call the library loop function often.
- Enable ping and pong if the library supports it.
- Limit how often you send, for example 10 to 20 times a second at most.
- Keep messages small, and avoid building large strings.
- Check the Wi-Fi signal and the supply for brownouts.
Why it happens
A WebSocket stays open only while both ends keep answering. Many libraries use ping and pong frames to check the peer is alive, and a blocked loop or a flood of frames makes one side’s pong or send time out and close the connection.
In the arduinoWebSockets library, enableHeartbeat takes a ping interval, a pong timeout and a count of missed pongs before it disconnects, and a count of 0 means it never disconnects. A user report describes freezes when a client vanished without notice, so keep the loop running and avoid long delays. The message rates suggested on this page are guidance, not a documented limit.
If you see this, do this
| You see | Do this |
|---|---|
| Drops after about a minute | No ping, or blocking code. |
| Drops when sending fast | Message rate or size too high. |
Related
delay and millis, brownout resets.
Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.
Why this happens
A WebSocket is a long-lived TCP connection. Neither side can tell the other end is still alive unless data or control frames keep flowing. Many servers send ping frames and expect a pong back within a set time; if one is missed, the connection is closed. On a small board the loop that answers those frames shares the processor with everything else, so one long delay in the loop is enough to miss it.
Memory is the second common cause. Each connected client needs buffers, and every String that you build and discard leaves the heap a little more fragmented. After some time, an allocation fails, and the library drops the client or the board resets. The Wi-Fi radio has a power-save mode that adds latency to incoming data, and disabling it with WiFi.setSleep(false) is a known way to make delivery more regular.
How to confirm the cause
- Print ESP.getFreeHeap() every few seconds. A value that keeps falling until the disconnect points to a leak or fragmentation.
- Measure the loop time. Store the previous millis() value and print the largest gap seen. Gaps of hundreds of milliseconds or more are blocking code.
- Read the close code on the browser side. In the browser console, the close event has a code; 1006 means the connection ended abnormally without a close frame, typical of a network drop or a stuck board.
- Watch the serial output for reset messages or brownout warnings. A board that reboots will drop its clients, and that looks like a disconnect.
- Print WiFi.RSSI(). A value much weaker than about -75 dBm leads to dropped packets and timeouts.
Worked example
A loop that services the socket constantly and sends on a timer without blocking (shown with the arduinoWebSockets server; adjust for your library):
unsigned long lastSend = 0;
void loop() {
webSocket.loop(); // service the socket every pass
if (millis() - lastSend >= 100) { // 10 messages per second
lastSend = millis();
webSocket.broadcastTXT("{\"t\":1}");
}
}Common mistakes
- Using delay(1000) in loop(), which stops all socket handling for a second.
- Building large String objects for every message instead of a fixed buffer.
- Sending as fast as the loop runs, which fills queues faster than the radio empties them.
- Writing client code with no reconnect logic, so the first dropped link ends the session.
- Testing only on a very weak signal and blaming the library.
If this did not fix it
- A router or proxy may close idle connections after a timeout. Regular small pings keep the connection busy.
- Browser tabs in the background can throttle timers and appear to disconnect.
- A power supply that dips when the radio transmits may reset the board; check for brownout messages.