diff --git a/frontend/src/file-manager.ts b/frontend/src/file-manager.ts index 30e9e7c..8f4d2cd 100644 --- a/frontend/src/file-manager.ts +++ b/frontend/src/file-manager.ts @@ -272,6 +272,11 @@ export class FileManager { socket.addEventListener('open', () => { if (!this.isCurrent(socket, generation)) return; + if (this.reconnectAttempts > 0) { + console.log( + `[WS-Reconnect] ${new Date().toISOString()} | SFTP | reconnect_success | attempt=${this.reconnectAttempts}/${RECONNECT_MAX_ATTEMPTS}`, + ); + } this.reconnectAttempts = 0; this.init(); }); diff --git a/frontend/src/process-manager.ts b/frontend/src/process-manager.ts index 39a6ece..1515874 100644 --- a/frontend/src/process-manager.ts +++ b/frontend/src/process-manager.ts @@ -293,6 +293,11 @@ export class ProcessManager { this.setStatus('正在启动进程监控…', 'Starting process monitor…'); socket.addEventListener('open', () => { if (!this.isCurrent(socket, generation)) return; + if (this.reconnectAttempts > 0) { + console.log( + `[WS-Reconnect] ${new Date().toISOString()} | Process | reconnect_success | attempt=${this.reconnectAttempts}/${RECONNECT_MAX_ATTEMPTS}`, + ); + } this.reconnectAttempts = 0; socket.send(JSON.stringify({ type: 'process_start' })); }); diff --git a/frontend/src/ws-reconnect.ts b/frontend/src/ws-reconnect.ts index c8d4fee..91933a0 100644 --- a/frontend/src/ws-reconnect.ts +++ b/frontend/src/ws-reconnect.ts @@ -106,6 +106,11 @@ export class WebSocketReconnectManager { private handleClose(event: CloseEvent): void { if (this.destroyed) return; + // Guard: ignore close events from superseded sockets that have been + // replaced by a newer attach() or a successful reconnect. Without + // this check a stale socket closing later could trigger a spurious + // reconnection cycle. + if (event.target !== this.socket) return; this.log({ timestamp: new Date().toISOString(),