Wire client SignalrService to the live .NET backend

- @microsoft/signalr client implementing OnlineService: REST auth, hub
  matchmaking, server-driven game state (onState), play/trump, reactions;
  delegates not-yet-server-backed features (profile/friends/shop/chat/rooms)
  to the mock. Selected via NEXT_PUBLIC_USE_SERVER=1 (NEXT_PUBLIC_SERVER_URL)
- game-store live mode: enterServerMatch + applyServerState (maps server DTO,
  hides opponent hands, tally + SFX), inputs route to the hub; no local engine
- MatchmakingScreen auto-enters the live match when the server signals ready
- Verified end-to-end via scripts/live-test.mjs (auth -> hub -> match -> state)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-04 13:13:48 +03:30
parent a3b797c8a3
commit ceccf70de7
11 changed files with 707 additions and 5 deletions
+42
View File
@@ -0,0 +1,42 @@
// End-to-end smoke test of the live SignalR backend (server must be running).
import { HubConnectionBuilder, LogLevel } from "@microsoft/signalr";
const SERVER = "http://localhost:5005";
const res = await fetch(`${SERVER}/api/auth/otp/verify`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ phone: "0912", code: "1234", name: "Tester" }),
});
const { token, userId } = await res.json();
if (!token) throw new Error("no token");
const conn = new HubConnectionBuilder()
.withUrl(`${SERVER}/hub/game`, { accessTokenFactory: () => token })
.configureLogging(LogLevel.Error)
.build();
let matchFound = false;
let states = 0;
let sawHand = false;
let phases = new Set();
let mySeat = null;
conn.on("matchFound", (m) => { matchFound = true; mySeat = m.seat; });
conn.on("state", (s) => {
states++;
phases.add(s.phase);
const me = s.players.find((p) => p.seat === s.mySeat);
if (me?.hand?.length) sawHand = true;
});
await conn.start();
await conn.invoke("StartMatchmaking", { name: "Tester", avatar: "a-fox", level: 3, plan: "pro" });
await new Promise((r) => setTimeout(r, 7000));
console.log(JSON.stringify({
userId, matchFound, mySeat, states, sawHand, phases: [...phases],
}));
await conn.stop();
process.exit(0);