From 08f44b9a9313de7a7ab1746c2d4c279b95569fc4 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 24 Mar 2026 17:25:06 -0700 Subject: [PATCH] Fix infinite reconnection loop caused by stale WebSocket onclose events When AttemptReconnect() disconnects a still-CONNECTING socket and creates a new one, the old socket's onclose fires asynchronously after Connect() clears m_disconnectedFlag, setting it back to 1. With connectedFlag=1 and disconnectedFlag=1 both stuck, the state machine bounces between STATE_CONNECTED and STATE_RECONNECTING every frame (30-60x/sec) without ever reaching the backoff timer or attempt limit. Guard all WebSocket event handlers to only modify shared flags when their socket is still the active one in Module._mpSockets. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../platforms/emscripten/websockettransport.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/extensions/src/multiplayer/platforms/emscripten/websockettransport.cpp b/extensions/src/multiplayer/platforms/emscripten/websockettransport.cpp index 41f33388..423c0701 100644 --- a/extensions/src/multiplayer/platforms/emscripten/websockettransport.cpp +++ b/extensions/src/multiplayer/platforms/emscripten/websockettransport.cpp @@ -52,8 +52,10 @@ void WebSocketTransport::Connect(const char* p_roomId) ws.binaryType = 'arraybuffer'; ws.onopen = function() { - Atomics.store(HEAP32, connPtr >> 2, 1); - Atomics.store(HEAP32, everConnPtr >> 2, 1); + if (Module._mpSockets[socketId] === ws) { + Atomics.store(HEAP32, connPtr >> 2, 1); + Atomics.store(HEAP32, everConnPtr >> 2, 1); + } }; ws.onmessage = function(event) { @@ -64,12 +66,16 @@ void WebSocketTransport::Connect(const char* p_roomId) }; ws.onclose = function() { - Atomics.store(HEAP32, connPtr >> 2, 0); - Atomics.store(HEAP32, discPtr >> 2, 1); + if (Module._mpSockets[socketId] === ws) { + Atomics.store(HEAP32, connPtr >> 2, 0); + Atomics.store(HEAP32, discPtr >> 2, 1); + } }; ws.onerror = function() { - Atomics.store(HEAP32, connPtr >> 2, 0); + if (Module._mpSockets[socketId] === ws) { + Atomics.store(HEAP32, connPtr >> 2, 0); + } }; Module._mpSockets[socketId] = ws;