fix(realtime): guarda cleanup de WebSocket em CONNECTING (StrictMode)
Fechar o socket ainda em CONNECTING (double-mount do StrictMode em dev) gerava "WebSocket is closed before the connection is established". closeSocket() adia o close para o onopen e neutraliza handlers; reconexão por queda inesperada intacta. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -44,11 +44,30 @@ function connect() {
|
||||
sock.onerror = () => { try { sock.close(); } catch { /* ignore */ } };
|
||||
}
|
||||
|
||||
// Fecha um socket que NÓS abrimos. Se ainda está em CONNECTING, chamar close()
|
||||
// agora dispara "WebSocket is closed before the connection is established"
|
||||
// (comum no double-mount do React StrictMode em DEV) → adiamos o close para o
|
||||
// onopen. Em todos os casos neutralizamos os handlers para o socket morto não
|
||||
// disparar reconexão (a reconexão automática por queda inesperada continua no
|
||||
// onclose original definido em connect()).
|
||||
function closeSocket(sock: WebSocket | null) {
|
||||
if (!sock) return;
|
||||
sock.onmessage = null;
|
||||
sock.onerror = null;
|
||||
sock.onclose = null;
|
||||
if (sock.readyState === WebSocket.CONNECTING) {
|
||||
sock.onopen = () => { try { sock.close(); } catch { /* ignore */ } };
|
||||
} else {
|
||||
sock.onopen = null;
|
||||
try { sock.close(); } catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
function ensureConnected() {
|
||||
const url = buildUrl();
|
||||
if (!url) return;
|
||||
// Clínica/token mudou → reconecta no canal certo.
|
||||
if (ws && url !== currentUrl) { try { ws.close(); } catch { /* ignore */ } ws = null; }
|
||||
if (ws && url !== currentUrl) { closeSocket(ws); ws = null; }
|
||||
if (!ws || ws.readyState === WebSocket.CLOSING || ws.readyState === WebSocket.CLOSED) connect();
|
||||
}
|
||||
|
||||
@@ -61,13 +80,13 @@ export const Realtime = {
|
||||
handlers.delete(handler);
|
||||
if (handlers.size === 0) {
|
||||
if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
|
||||
if (ws) { try { ws.close(); } catch { /* ignore */ } ws = null; }
|
||||
if (ws) { closeSocket(ws); ws = null; }
|
||||
}
|
||||
};
|
||||
},
|
||||
/** Força reconexão (ex.: ao trocar de workspace). */
|
||||
reconnect() {
|
||||
if (ws) { try { ws.close(); } catch { /* ignore */ } ws = null; }
|
||||
if (ws) { closeSocket(ws); ws = null; }
|
||||
backoff = 1000;
|
||||
ensureConnected();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user