import { EventEmitter } from 'events' const log = require('electron-log') class ReconnectManager extends EventEmitter { constructor() { super() this.reconnectTimers = new Map() // IP -> timer对象 this.reconnectAttempts = new Map() // IP -> 当前重连次数 this.reconnectConfig = { enabled: false, interval: 5, // 秒 maxAttempts: 10 } this.isReconnecting = new Map() // IP -> boolean,防止重复重连 } // 更新重连配置 updateConfig(config) { this.reconnectConfig = { ...this.reconnectConfig, ...config, interval: Math.max(4, config.interval || this.reconnectConfig.interval) // 最小4秒 } log.info('Reconnect config updated:', this.reconnectConfig) } // 启动重连 startReconnect(ip, reason = 'Connection lost') { if (!this.reconnectConfig.enabled) { log.info(`Reconnect disabled for ${ip}`) return } // 防止重复启动重连 if (this.isReconnecting.get(ip)) { log.warn(`Reconnect already in progress for ${ip}`) return } this.isReconnecting.set(ip, true) // 如果没有当前重连次数,初始化为0 if (!this.reconnectAttempts.has(ip)) { this.reconnectAttempts.set(ip, 0) } log.info(`${reason}, starting reconnect for ${ip}...`) // 发送重连状态更新 this.emit('reconnect-status', { ip, isReconnecting: true }) // 设置重连定时器 this.scheduleNextAttempt(ip) } // 安排下次重连尝试 scheduleNextAttempt(ip) { // 递增重连次数 const currentAttempts = this.reconnectAttempts.get(ip) || 0 const newAttempts = currentAttempts + 1 this.reconnectAttempts.set(ip, newAttempts) if (newAttempts > this.reconnectConfig.maxAttempts) { log.error( `Max reconnect attempts reached for ${ip} (${newAttempts}/${this.reconnectConfig.maxAttempts})` ) this.stopReconnect(ip, 'Max attempts reached') return } log.info( `Scheduling reconnect attempt ${newAttempts}/${this.reconnectConfig.maxAttempts} for ${ip}` ) const intervalMs = this.reconnectConfig.interval * 1000 log.info(`Reconnect timer set for ${ip} in ${this.reconnectConfig.interval}s (${intervalMs}ms)`) const timer = setTimeout(() => { log.info(`Reconnect timer fired for ${ip}, executing attempt ${newAttempts}`) this.executeReconnectAttempt(ip) }, intervalMs) // 清除之前的定时器 this.clearTimer(ip) this.reconnectTimers.set(ip, timer) } // 执行重连尝试 executeReconnectAttempt(ip) { const attempts = this.reconnectAttempts.get(ip) || 0 log.info( `Executing reconnect attempt ${attempts}/${this.reconnectConfig.maxAttempts} for ${ip}` ) // 发出重连请求事件 this.emit('attempt-reconnect', ip, (success, error) => { if (success) { log.info(`Reconnect attempt ${attempts} successful for ${ip}`) this.onReconnectSuccess(ip) } else { log.warn(`Reconnect attempt ${attempts} failed for ${ip}: ${error?.message || error}`) this.onReconnectFailure(ip, error) } }) } // 重连成功处理 onReconnectSuccess(ip) { const attempts = this.reconnectAttempts.get(ip) || 0 log.info(`Reconnect attempt ${attempts} successful for ${ip}, clearing reconnect state`) // 停止重连 this.stopReconnect(ip, 'Reconnect successful') } // 重连失败处理 onReconnectFailure(ip, error) { const attempts = this.reconnectAttempts.get(ip) || 0 log.warn( `Reconnect attempt ${attempts} failed for ${ip}, scheduling next attempt in ${this.reconnectConfig.interval}s`, error ) // 发送重连状态更新 this.emit('reconnect-status', { ip, isReconnecting: true }) // 安排下次重连 this.scheduleNextAttempt(ip) } // 停止重连 stopReconnect(ip, reason = 'Manual stop') { log.info(`Stopping reconnect for ${ip}: ${reason}`) this.clearTimer(ip) this.reconnectAttempts.delete(ip) this.isReconnecting.set(ip, false) // 发送重连状态更新 this.emit('reconnect-status', { ip, isReconnecting: false }) } // 清除重连定时器 clearTimer(ip) { const timer = this.reconnectTimers.get(ip) if (timer) { clearTimeout(timer) this.reconnectTimers.delete(ip) log.debug(`Cleared reconnect timer for ${ip}`) } } // 重置重连计数 resetAttempts(ip) { this.reconnectAttempts.set(ip, 0) log.debug(`Reset reconnect attempts for ${ip}`) } // 检查是否正在重连 isReconnectInProgress(ip) { return this.isReconnecting.get(ip) || false } // 获取重连状态 getReconnectStatus(ip) { return { isReconnecting: this.isReconnecting.get(ip) || false, attempts: this.reconnectAttempts.get(ip) || 0, maxAttempts: this.reconnectConfig.maxAttempts, config: this.reconnectConfig } } // 获取所有重连状态 getAllReconnectStatus() { const status = {} for (const [ip] of this.isReconnecting) { status[ip] = this.getReconnectStatus(ip) } return status } // 清理指定IP的所有重连状态 cleanup(ip) { log.info(`Cleaning up reconnect state for ${ip}`) this.clearTimer(ip) this.reconnectAttempts.delete(ip) this.isReconnecting.delete(ip) } // 清理所有重连状态 cleanupAll() { log.info('Cleaning up all reconnect states') // 清除所有定时器 for (const [ip] of this.reconnectTimers) { this.clearTimer(ip) } // 清除所有状态 this.reconnectAttempts.clear() this.isReconnecting.clear() } // 获取配置 getConfig() { return { ...this.reconnectConfig } } } export default ReconnectManager