mirror of
https://github.com/tiennm99/gomoku.git
synced 2026-07-29 12:20:12 +00:00
Bug: after clicking "Leave" on the game-over modal, the client landed on the nickname entry screen and got stuck — typing a nickname produced no response for up to 90 seconds. Root cause chain: 1. Server handleClientExit (stateless) closed SendCh and nilled it but did not close the WS connection. Writer goroutine drained + exited without closing the conn; reader stayed blocked on ReadMessage; state machine stayed blocked on CmdCh. Zombie session. 2. Any subsequent player.Send() returned nil (SendCh was nil), silently dropping responses. The setNickname reply never reached the client. 3. Client only unstuck when reader's 90 s readDeadline fired, finally closing the WS and triggering the auto-reconnect path. 4. Client MenuScene.create() always called showNicknameScreen() without checking gameState.nickname, so even after the reconnect the user had to re-type their name. Fix: "exit" now means "leave current room, return to home lobby" — not "terminate WS session". Server: - dispatch.go: move Request_ClientExit from stateless to stateful path. - handlers_stateless.go: delete handleClientExit entirely. - waiting.go leaveRoom: broadcast ClientExitResponse via broadcastResponse BEFORE removing the player, so the exiting player also receives their own exit confirmation. Removes duplicated self-notification logic. - waiting/gamePvp/gamePve/gameover/watching: on ClientExitRequest, call leaveRoom + return consts.StateHome (was return 0, ErrClientExit). - home.go: on ClientExitRequest, send bare ClientExitResponse and stay in home (no room to leave). - Update 4 state tests that asserted ErrClientExit → now assert StateHome. - Rename TestWatching_ClientExitReturnsErrClientExit → ReturnsHome. Client: - menu-scene.js create(): if gameState.nickname is set, skip nickname screen and call showLobby() directly. Otherwise showNicknameScreen(). - game-scene.js _onClientExit: drop the explicit showLobby() call; let MenuScene.create() decide the panel based on nickname state. Remove now-unused menu-ui showLobby import. Result: click Leave → server sends ClientExitResponse, state machine transitions to StateHome, WS stays open, client transitions to MenuScene → sees gameState.nickname is set → goes straight to lobby. No reconnect, no re-typing, no 90-second stall. go vet + go test ./... green. npm run build green.