9f11896f7bb8bc2493a9bf28f325829cb57780f6
The PvP waiting-room timeout path in BattleNodeWebSocketHandler used to return immediately after RemovePending, leaving the parked first arriver to learn about the disconnect via TCP teardown after Kestrel finished draining the request. BestHTTP / socket.io-client log that as an abrupt drop rather than a controlled disconnect. New TryPoliteCloseAsync helper emits an EIO "1" (Close) text frame, then runs the WebSocket close handshake with NormalClosure. Wrapped in try/catch + Debug log — teardown races between the server-side close and client disconnect are routine and not actionable. Uses a fresh 5s CTS so ctx.RequestAborted being canceled doesn't skip the close. Wired into both bail-out paths post-AcceptWebSocketAsync that previously just returned: - PvP waiting-room timeout / Park-Park race (the main case, per PLAN.md L104 (c)) - Unknown BattleType default case (same shape, log message already said "closing WS" but didn't actually close — opportunistic fix) PvpWaitingRoomTimeout integration test tightened: now asserts the polite "1" text frame arrives before the close handshake, not just that the WS eventually closes by any means. 172 battle-node tests passing (was 172 before the assertion tightening; the existing timeout test stayed in.) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Description
The SV Simulator server code, including the DCG Engine, SVSim content, and an entrypoint for the official game client.
Languages
C#
100%