fix(signalr): force Long-Polling transport so the hub connects through nginx
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 47s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 1m11s

Server logs showed REST working but ZERO hub activity — the SignalR WebSocket
upgrade isn't getting through the nginx/CDN stack and auto-fallback wasn't
recovering, so StartMatchmaking never reached the server (matchmaking spun
forever). Force the HttpTransportType.LongPolling transport — plain HTTP that
already works (same path as REST); SignalR holds the poll open so it's
effectively real-time for a turn-based game. Revertable once the api block
proxies WS upgrades.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-15 22:37:04 +03:30
parent f059065d4b
commit fefa9e2e3a
+9 -4
View File
@@ -141,10 +141,15 @@ export class SignalrService implements OnlineService {
private async connect(): Promise<void> { private async connect(): Promise<void> {
if (this.conn || !this.token) return; if (this.conn || !this.token) return;
const conn = new signalR.HubConnectionBuilder() const conn = new signalR.HubConnectionBuilder()
// Normal negotiate flow → auto-picks the best transport (WS, else SSE / // Force Long-Polling: plain HTTP POST/GET that works through the existing
// long-poll). Requires api.bargevasat.ir to BYPASS the CDN (WCDN 404s the // nginx/CDN (same path REST already uses) without needing WebSocket-upgrade
// negotiate POST); with the CDN bypassed this is the most robust path. // headers. SignalR holds the poll open, so for a turn-based game it's
.withUrl(`${SERVER}/hub/game`, { accessTokenFactory: () => this.token ?? "" }) // effectively real-time. Switch back to default transports once the api
// server block proxies WS upgrades.
.withUrl(`${SERVER}/hub/game`, {
accessTokenFactory: () => this.token ?? "",
transport: signalR.HttpTransportType.LongPolling,
})
.withAutomaticReconnect() .withAutomaticReconnect()
.configureLogging(signalR.LogLevel.Warning) .configureLogging(signalR.LogLevel.Warning)
.build(); .build();