fix(room-ws): try reconnect with existing token before requesting new

On auto-reconnect (scheduleReconnect), attempt connection with the stored
wsToken first. If the WS closes immediately (server rejected the token),
fall back to fetching a fresh token and retrying. Only requests a new
token when the existing one fails or when connect() is called manually
with forceNewToken=true.
This commit is contained in:
ZhenYi 2026-04-17 21:40:07 +08:00
parent 309bc50e86
commit b70d91866c

View File

@ -133,7 +133,7 @@ export class RoomWsClient {
return new Set(this.subscribedProjects);
}
async connect(): Promise<void> {
async connect(forceNewToken = false): Promise<void> {
if (this.ws && this.status === 'open') {
return;
}
@ -141,7 +141,9 @@ export class RoomWsClient {
this.shouldReconnect = true;
this.setStatus('connecting');
// Fetch a fresh token for each connection attempt (backend consumes token on use)
// Fetch a fresh token unless we have a valid existing one and not forcing.
// When forceNewToken=false (reconnect path), try existing token first.
if (forceNewToken || !this.wsToken) {
try {
const tokenResp = await fetch(`${this.baseUrl}/api/ws/token`, {
method: 'POST',
@ -164,6 +166,7 @@ export class RoomWsClient {
this.callbacks.onError?.(err instanceof Error ? err : new Error(String(err)));
throw err;
}
}
const wsUrl = this.buildWsUrl();
console.debug('[RoomWs] Connecting to:', wsUrl);
@ -172,6 +175,13 @@ export class RoomWsClient {
// Guard: if ws is closed before handlers are set, skip
if (this.ws.readyState === WebSocket.CLOSED || this.ws.readyState === WebSocket.CLOSING) {
console.warn('[RoomWs] WebSocket closed immediately');
// If we used an existing token and it was immediately rejected, retry with a new token
if (!forceNewToken && this.wsToken) {
console.debug('[RoomWs] Existing token rejected — fetching new token and retrying');
const savedToken = this.wsToken;
this.wsToken = null;
return this.connect(true);
}
return;
}