Files
rplace/wrangler.json
T
tiennm99 4f02d30393 feat(canvas): WS hardening, client race fix, and ping/pong heartbeat
Server:
- Origin allowlist on /api/ws (env.ALLOWED_ORIGINS, comma-separated; empty
  = allow all for dev/preview)
- per-identity WS connection cap (MAX_WS_PER_IDENTITY = 5) using
  acceptWebSocket(socket, [identity]) tagging; 6th upgrade returns 429
- ws.send 'ping' triggers a {type:'pong'} reply so dead connections fire
  onclose promptly instead of waiting on TCP keepalive

Client:
- buffer WS pixels arriving during the initial canvas fetch and replay
  them after committedColors is replaced; previously the post-fetch
  Uint8Array assignment silently overwrote any pixels broadcast in the
  fetch window (the documented C2 race)
- 30s ping / 60s pong watchdog closes the socket if pong stops arriving,
  routing through the existing exponential-backoff reconnect path

Tests:
- four /api/ws cases: missing upgrade, disallowed origin, allowed origin,
  empty allowlist (dev default). Sentinel uses status 200 because undici
  rejects 101 in Node-side Response constructors.

Plan: plans/260510-0232-fix-do-migration-followups/phase-03-ws-hardening-client-race.md
2026-05-10 03:05:56 +07:00

36 lines
583 B
JSON

{
"name": "rplace",
"main": "src/worker.js",
"compatibility_date": "2025-04-01",
"assets": {
"directory": "dist"
},
"durable_objects": {
"bindings": [
{
"name": "CANVAS_ROOM",
"class_name": "CanvasRoom"
}
]
},
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["CanvasRoom"]
}
],
"observability": {
"logs": {
"enabled": true,
"invocation_logs": true
},
"traces": {
"enabled": true
}
},
"vars": {
"ALLOWED_ORIGINS": "",
"ENVIRONMENT": "development"
}
}