Skip to content

feat(multiplayer): close outdated clients with a protocol version handshake - #27

Merged
verlyn13 merged 1 commit into
mainfrom
feat/protocol-handshake
Sep 14, 2026
Merged

verlyn13 merged 1 commit into
mainfrom
feat/protocol-handshake

Conversation

@verlyn13

Copy link
Copy Markdown
Member

Summary

Roadmap section 1 step 3: the protocol version handshake. Policy: current protocol or refresh.

  • packages/shared/src/protocol.ts: GAME_PROTOCOL_VERSION = 1, query parameter protocol, close code 4426 and reason upgrade_required.
  • Clients: the lobby, room and spectator sockets append ?protocol=1. The /ws/lobby and /ws/room/[code] proxies forward only that parameter (plus role) and still replace Authorization with the session bearer. Previously the lobby route dropped the query string entirely.
  • Durable Objects: lib/protocol-gate.ts runs first in GameRoom.fetch and GlobalLobby.fetch. A missing or different version gets a 101 whose socket is closed at once with 4426 via plain accept(), so it never counts as presence and never reaches webSocketClose. The rejection is logged with the structured logger.
  • Web: on 4426, reconnect loops stop and protocolUpgrade takes over. It reloads once (time recorded in sessionStorage). If a second 4426 arrives within 2 minutes, UpdateRequiredBanner shows "Dicee is updating. Try again in a minute." with a retry button. If storage is unavailable, it never auto-reloads. Every other close code behaves as before.
  • Docs:
    • Architecture Clients section.
    • Roadmap drops the finished step.
    • First-release order (status action 3, roadmap step 4, cloudflare.md cutover): deploy dicee-web and move the domain before deploying dicee, and use operator commands rather than a CI dispatch. Today's Pages client sends no version, so the gated dicee would close its sockets.

Known rollout effect: tabs already open when the gated dicee ships run old code that sends no version and does not recognise 4426. They need one manual reload. The reload logic protects future version bumps.

No deployment.

Verification

  • Agent (worktree):
    • Worker test:agent: 519 passed. The integration file needs a loopback port and passed 15/15 alone outside the sandbox.
    • New handshake tests 12/12: lobby, room player and spectator × missing, mismatched and current version, plus router passthrough and shared exports.
    • Web test:agent: 1625 passed, including the workerd proxy runtime test for 4426 before the 101.
    • pnpm check and pnpm lint pass apart from a docs finding that clears once the new files are tracked.
  • Integration: rebased onto feat(web): serve the web app from a dicee-web Worker on Workers Static Assets #26; node scripts/check-docs.mjs and git diff --check on the squashed commit; pre-push pnpm validate:ci; CI and CodeQL on this PR.
  • Not verified: real workerd Durable Object runtime and browser end-to-end.

…dshake

Every lobby, room and spectator socket sends GAME_PROTOCOL_VERSION (packages/shared/src/protocol.ts) as a non-secret query parameter; the web proxy routes forward it. GameRoom and GlobalLobby check it before any room, seat or presence work and close a missing or different version with application code 4426 (upgrade_required) on a socket that never joins the hibernation set.

On 4426 the lobby store and the room and spectator services stop reconnecting and hand off to protocolUpgrade: reload once, recording the time in sessionStorage; a second 4426 within two minutes shows 'Dicee is updating. Try again in a minute.' instead of looping, and without storage it never auto-reloads. No compatibility shims: current protocol or refresh.

Docs: roadmap section 1 drops the finished step; the first release deploys dicee-web and moves the domain before deploying dicee, because today's Pages client sends no version (status action 3, cloudflare.md cutover).
@verlyn13
verlyn13 merged commit 77611af into main Sep 14, 2026
8 checks passed
@verlyn13
verlyn13 deleted the feat/protocol-handshake branch September 14, 2026 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant