光电挠度仪上位机
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

221 lines
5.7 KiB

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