← Notes

Answer the Ping on the Socket That Received It

1 min read#WebSocket#Android

The Android client opened 159 WebSocket connections in a day, with 160 abnormal closes. Three small bugs stacked up, and every return to the foreground left one more zombie connection.

First: a forced reconnect only closed the old connection when the address had changed; with the same address it just opened a new one and left the old one in place. Second: the pong replying to the server’s ping was sent through the “current connection” reference rather than the connection that received the ping, so old connections never answered and could only be kicked out by the server’s heartbeat timeout. Third: every return to the foreground forced a reconnect unconditionally.

The server had its half too: removing a connection from the registry deleted the record without closing the socket, leaving half-open connections the server couldn’t see and the client still thought were live.

Each fix is small: close the old connection before building a new one; close any connection that gets superseded; send the pong on the connection that received the ping; if already connected, only resync state instead of reconnecting; and after the server deregisters a connection, close it outside the lock.

Written byShihao Qi