fix(ext): v0.5.8 false positive zombie socket disconnect bug resolve (timestamp replace setTimeout)
This commit is contained in:
@@ -122,8 +122,8 @@ export class WSBridgeClient {
|
||||
private reconnectDelay = INITIAL_RECONNECT_DELAY;
|
||||
private reconnectTimer: NodeJS.Timeout | null = null;
|
||||
private heartbeatTimer: NodeJS.Timeout | null = null;
|
||||
private pongTimeoutTimer: NodeJS.Timeout | null = null;
|
||||
private authTimer: NodeJS.Timeout | null = null;
|
||||
private lastPongTime: number = 0;
|
||||
|
||||
// Message queue (survives reconnection)
|
||||
private messageQueue: WSMessage[] = [];
|
||||
@@ -240,16 +240,9 @@ export class WSBridgeClient {
|
||||
this._onDisconnect();
|
||||
});
|
||||
|
||||
ws.on('error', (err: Error) => {
|
||||
this.logFn(`[WS] Error: ${err.message}`);
|
||||
});
|
||||
|
||||
ws.on('pong', () => {
|
||||
// Server responded to our ping — connection is alive
|
||||
if (this.pongTimeoutTimer) {
|
||||
clearTimeout(this.pongTimeoutTimer);
|
||||
this.pongTimeoutTimer = null;
|
||||
}
|
||||
this.lastPongTime = Date.now();
|
||||
});
|
||||
} else {
|
||||
// ─── Browser-style WebSocket API (.onopen / .onmessage) ───
|
||||
@@ -348,6 +341,7 @@ export class WSBridgeClient {
|
||||
this.instanceNumber = authOk.instance_number;
|
||||
this.sessionToken = authOk.session_token;
|
||||
this.reconnectDelay = INITIAL_RECONNECT_DELAY;
|
||||
this.lastPongTime = Date.now(); // Reset pong timer on auth
|
||||
|
||||
if (this.authTimer) {
|
||||
clearTimeout(this.authTimer);
|
||||
@@ -470,20 +464,20 @@ export class WSBridgeClient {
|
||||
this._stopHeartbeat();
|
||||
this.heartbeatTimer = setInterval(() => {
|
||||
if (this.ws && this.connected) {
|
||||
// Check for zombie connection (no pong for 60s)
|
||||
if (Date.now() - this.lastPongTime > 60000) {
|
||||
this.logFn('[WS] Heartbeat timeout — no pong received for 60s (zombie connection), terminating');
|
||||
if (this.ws) {
|
||||
try { this.ws.terminate(); } catch { try { this.ws.close(); } catch { } }
|
||||
}
|
||||
this._onDisconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Node.js ws has .ping(), browser WebSocket doesn't
|
||||
if (typeof this.ws.ping === 'function') {
|
||||
this.ws.ping();
|
||||
|
||||
// Set timeout waiting for pong
|
||||
if (this.pongTimeoutTimer) clearTimeout(this.pongTimeoutTimer);
|
||||
this.pongTimeoutTimer = setTimeout(() => {
|
||||
this.logFn('[WS] Heartbeat timeout — no pong received, terminating connection');
|
||||
if (this.ws) {
|
||||
try { this.ws.terminate(); } catch { try { this.ws.close(); } catch { } }
|
||||
}
|
||||
this._onDisconnect();
|
||||
}, 10000); // 10s timeout
|
||||
} else {
|
||||
// Fallback: send heartbeat as JSON message
|
||||
this.ws.send(JSON.stringify({ type: 'heartbeat' }));
|
||||
@@ -500,10 +494,6 @@ export class WSBridgeClient {
|
||||
clearInterval(this.heartbeatTimer);
|
||||
this.heartbeatTimer = null;
|
||||
}
|
||||
if (this.pongTimeoutTimer) {
|
||||
clearTimeout(this.pongTimeoutTimer);
|
||||
this.pongTimeoutTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Reconnection ───
|
||||
@@ -559,11 +549,6 @@ export class WSBridgeClient {
|
||||
this.reconnectTimer = null;
|
||||
}
|
||||
|
||||
if (this.pongTimeoutTimer) {
|
||||
clearTimeout(this.pongTimeoutTimer);
|
||||
this.pongTimeoutTimer = null;
|
||||
}
|
||||
|
||||
if (this.ws) {
|
||||
try {
|
||||
this.ws.close();
|
||||
|
||||
Reference in New Issue
Block a user