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);
|
return new Set(this.subscribedProjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect(): Promise<void> {
|
async connect(forceNewToken = false): Promise<void> {
|
||||||
if (this.ws && this.status === 'open') {
|
if (this.ws && this.status === 'open') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -141,28 +141,31 @@ export class RoomWsClient {
|
|||||||
this.shouldReconnect = true;
|
this.shouldReconnect = true;
|
||||||
this.setStatus('connecting');
|
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.
|
||||||
try {
|
// When forceNewToken=false (reconnect path), try existing token first.
|
||||||
const tokenResp = await fetch(`${this.baseUrl}/api/ws/token`, {
|
if (forceNewToken || !this.wsToken) {
|
||||||
method: 'POST',
|
try {
|
||||||
credentials: 'include',
|
const tokenResp = await fetch(`${this.baseUrl}/api/ws/token`, {
|
||||||
});
|
method: 'POST',
|
||||||
if (!tokenResp.ok) {
|
credentials: 'include',
|
||||||
const text = await tokenResp.text().catch(() => '');
|
});
|
||||||
console.error(`[RoomWs] Token fetch failed: ${tokenResp.status} ${tokenResp.statusText} — ${text}`);
|
if (!tokenResp.ok) {
|
||||||
throw new Error(`Token fetch failed: ${tokenResp.status}`);
|
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();
|
const wsUrl = this.buildWsUrl();
|
||||||
@ -172,6 +175,13 @@ export class RoomWsClient {
|
|||||||
// Guard: if ws is closed before handlers are set, skip
|
// Guard: if ws is closed before handlers are set, skip
|
||||||
if (this.ws.readyState === WebSocket.CLOSED || this.ws.readyState === WebSocket.CLOSING) {
|
if (this.ws.readyState === WebSocket.CLOSED || this.ws.readyState === WebSocket.CLOSING) {
|
||||||
console.warn('[RoomWs] WebSocket closed immediately');
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user