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:
parent
309bc50e86
commit
b70d91866c
@ -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,28 +141,31 @@ export class RoomWsClient {
|
||||
this.shouldReconnect = true;
|
||||
this.setStatus('connecting');
|
||||
|
||||
// Fetch a fresh token for each connection attempt (backend consumes token on use)
|
||||
try {
|
||||
const tokenResp = await fetch(`${this.baseUrl}/api/ws/token`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!tokenResp.ok) {
|
||||
const text = await tokenResp.text().catch(() => '');
|
||||
console.error(`[RoomWs] Token fetch failed: ${tokenResp.status} ${tokenResp.statusText} — ${text}`);
|
||||
throw new Error(`Token fetch failed: ${tokenResp.status}`);
|
||||
// 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',
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!tokenResp.ok) {
|
||||
const text = await tokenResp.text().catch(() => '');
|
||||
console.error(`[RoomWs] Token fetch failed: ${tokenResp.status} ${tokenResp.statusText} — ${text}`);
|
||||
throw new Error(`Token fetch failed: ${tokenResp.status}`);
|
||||
}
|
||||
const tokenData = await tokenResp.json();
|
||||
this.wsToken = tokenData.data?.token || null;
|
||||
if (!this.wsToken) {
|
||||
console.error('[RoomWs] Token is empty — not logged in?');
|
||||
throw new Error('No WS token received');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[RoomWs] Failed to fetch WS token:', err);
|
||||
this.setStatus('error');
|
||||
this.callbacks.onError?.(err instanceof Error ? err : new Error(String(err)));
|
||||
throw err;
|
||||
}
|
||||
const tokenData = await tokenResp.json();
|
||||
this.wsToken = tokenData.data?.token || null;
|
||||
if (!this.wsToken) {
|
||||
console.error('[RoomWs] Token is empty — not logged in?');
|
||||
throw new Error('No WS token received');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[RoomWs] Failed to fetch WS token:', err);
|
||||
this.setStatus('error');
|
||||
this.callbacks.onError?.(err instanceof Error ? err : new Error(String(err)));
|
||||
throw err;
|
||||
}
|
||||
|
||||
const wsUrl = this.buildWsUrl();
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user