From a7aac985d288f07ae6d7f91c4f1836a6bb627f59 Mon Sep 17 00:00:00 2001 From: Jan Willem Mannaerts Date: Tue, 3 Mar 2026 13:42:51 +0100 Subject: [PATCH] Clean up session participants on socket disconnect When a user closes their browser or navigates away, the socket disconnects without emitting poker:leave. The participant stayed in the NATS session data indefinitely. Now the disconnect handler iterates the socket's poker rooms and calls leaveSession for each, then broadcasts the updated state to remaining participants. Co-Authored-By: Claude Opus 4.6 --- backend/src/index.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/src/index.js b/backend/src/index.js index e92ee7c..3736d98 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -194,7 +194,23 @@ io.on('connection', (socket) => { websocketConnections.inc(); trackUniqueUser(user.jiraAccountId); trackUniqueTenant(user.jiraCloudId); - socket.on('disconnect', () => { websocketConnections.dec(); }); + socket.on('disconnect', async () => { + websocketConnections.dec(); + for (const room of socket.rooms) { + if (!room.startsWith('poker:')) continue; + const sessionId = room.slice(6); + try { + await leaveSession({ + sessionId, + tenantCloudId: socket.user.jiraCloudId, + userKey: socket.user.jiraAccountId + }); + await emitSessionState(sessionId, socket.user.jiraCloudId); + } catch { + // best-effort cleanup + } + } + }); const throttled = socketThrottle(socket); throttled('poker:join', async ({ sessionId }) => {