/** * 连接状态管理器 * 负责跟踪连接状态变化、状态变化通知和自动恢复逻辑 */ import { createLogger, ITimer } from '@esengine/ecs-framework'; import { ConnectionState, EventEmitter } from '@esengine/network-shared'; import { NetworkTimerManager } from '../utils'; /** * 状态转换规则 */ export interface StateTransitionRule { from: ConnectionState; to: ConnectionState; condition?: () => boolean; action?: () => void; } /** * 连接状态管理器配置 */ export interface ConnectionStateManagerConfig { enableAutoRecovery: boolean; recoveryTimeout: number; maxRecoveryAttempts: number; stateTimeout: number; enableStateValidation: boolean; logStateChanges: boolean; } /** * 状态历史记录 */ export interface StateHistoryEntry { state: ConnectionState; timestamp: number; duration?: number; reason?: string; metadata?: Record; } /** * 状态统计信息 */ export interface StateStats { currentState: ConnectionState; totalTransitions: number; stateHistory: StateHistoryEntry[]; stateDurations: Record; averageStateDurations: Record; totalUptime: number; totalDowntime: number; connectionAttempts: number; successfulConnections: number; failedConnections: number; } /** * 连接状态管理器事件接口 */ export interface ConnectionStateManagerEvents { stateChanged: (oldState: ConnectionState, newState: ConnectionState, reason?: string) => void; stateTimeout: (state: ConnectionState, duration: number) => void; recoveryStarted: (attempt: number) => void; recoverySucceeded: () => void; recoveryFailed: (maxAttemptsReached: boolean) => void; invalidTransition: (from: ConnectionState, to: ConnectionState) => void; } /** * 连接状态管理器 */ export class ConnectionStateManager extends EventEmitter { private logger = createLogger('ConnectionStateManager'); private config: ConnectionStateManagerConfig; private currentState: ConnectionState = ConnectionState.Disconnected; private previousState?: ConnectionState; private stateStartTime: number = Date.now(); private stats: StateStats; // 状态管理 private stateHistory: StateHistoryEntry[] = []; private transitionRules: StateTransitionRule[] = []; private stateTimeouts: Map = new Map(); // 恢复逻辑 private recoveryAttempts = 0; private recoveryTimer?: ITimer; // Timer管理器使用静态的NetworkTimerManager private recoveryCallback?: () => Promise; // 事件处理器 private eventHandlers: Partial = {}; /** * 构造函数 */ constructor(config: Partial = {}) { super(); this.config = { enableAutoRecovery: true, recoveryTimeout: 5000, maxRecoveryAttempts: 3, stateTimeout: 30000, enableStateValidation: true, logStateChanges: true, ...config }; this.stats = { currentState: this.currentState, totalTransitions: 0, stateHistory: [], stateDurations: { [ConnectionState.Disconnected]: [], [ConnectionState.Connecting]: [], [ConnectionState.Connected]: [], [ConnectionState.Reconnecting]: [], [ConnectionState.Failed]: [] }, averageStateDurations: { [ConnectionState.Disconnected]: 0, [ConnectionState.Connecting]: 0, [ConnectionState.Connected]: 0, [ConnectionState.Reconnecting]: 0, [ConnectionState.Failed]: 0 }, totalUptime: 0, totalDowntime: 0, connectionAttempts: 0, successfulConnections: 0, failedConnections: 0 }; this.initializeDefaultTransitionRules(); } /** * 设置当前状态 */ setState(newState: ConnectionState, reason?: string, metadata?: Record): boolean { if (this.currentState === newState) { return true; } // 验证状态转换 if (this.config.enableStateValidation && !this.isValidTransition(this.currentState, newState)) { this.logger.warn(`无效的状态转换: ${this.currentState} -> ${newState}`); this.eventHandlers.invalidTransition?.(this.currentState, newState); return false; } const oldState = this.currentState; const now = Date.now(); const duration = now - this.stateStartTime; // 更新状态历史 this.updateStateHistory(oldState, duration, reason, metadata); // 清理旧状态的超时定时器 this.clearStateTimeout(oldState); // 更新当前状态 this.previousState = oldState; this.currentState = newState; this.stateStartTime = now; this.stats.currentState = newState; this.stats.totalTransitions++; // 更新连接统计 this.updateConnectionStats(oldState, newState); if (this.config.logStateChanges) { this.logger.info(`连接状态变化: ${oldState} -> ${newState}${reason ? ` (${reason})` : ''}`); } // 设置新状态的超时定时器 this.setStateTimeout(newState); // 处理自动恢复逻辑 this.handleAutoRecovery(newState); // 触发事件 this.eventHandlers.stateChanged?.(oldState, newState, reason); this.emit('stateChanged', oldState, newState, reason); return true; } /** * 获取当前状态 */ getState(): ConnectionState { return this.currentState; } /** * 获取上一个状态 */ getPreviousState(): ConnectionState | undefined { return this.previousState; } /** * 获取当前状态持续时间 */ getCurrentStateDuration(): number { return Date.now() - this.stateStartTime; } /** * 获取状态统计信息 */ getStats(): StateStats { this.updateCurrentStats(); return { ...this.stats, stateHistory: [...this.stateHistory] }; } /** * 重置统计信息 */ resetStats(): void { this.stats = { currentState: this.currentState, totalTransitions: 0, stateHistory: [], stateDurations: { [ConnectionState.Disconnected]: [], [ConnectionState.Connecting]: [], [ConnectionState.Connected]: [], [ConnectionState.Reconnecting]: [], [ConnectionState.Failed]: [] }, averageStateDurations: { [ConnectionState.Disconnected]: 0, [ConnectionState.Connecting]: 0, [ConnectionState.Connected]: 0, [ConnectionState.Reconnecting]: 0, [ConnectionState.Failed]: 0 }, totalUptime: 0, totalDowntime: 0, connectionAttempts: 0, successfulConnections: 0, failedConnections: 0 }; this.stateHistory.length = 0; this.recoveryAttempts = 0; } /** * 设置恢复回调 */ setRecoveryCallback(callback: () => Promise): void { this.recoveryCallback = callback; } /** * 添加状态转换规则 */ addTransitionRule(rule: StateTransitionRule): void { this.transitionRules.push(rule); } /** * 移除状态转换规则 */ removeTransitionRule(from: ConnectionState, to: ConnectionState): boolean { const index = this.transitionRules.findIndex((rule) => rule.from === from && rule.to === to); if (index >= 0) { this.transitionRules.splice(index, 1); return true; } return false; } /** * 检查状态转换是否有效 */ isValidTransition(from: ConnectionState, to: ConnectionState): boolean { // 检查自定义转换规则 const rule = this.transitionRules.find((r) => r.from === from && r.to === to); if (rule) { return rule.condition ? rule.condition() : true; } // 默认转换规则 return this.isDefaultValidTransition(from, to); } /** * 检查是否为连接状态 */ isConnected(): boolean { return this.currentState === ConnectionState.Connected; } /** * 检查是否为连接中状态 */ isConnecting(): boolean { return this.currentState === ConnectionState.Connecting || this.currentState === ConnectionState.Reconnecting; } /** * 检查是否为断开连接状态 */ isDisconnected(): boolean { return this.currentState === ConnectionState.Disconnected || this.currentState === ConnectionState.Failed; } /** * 手动触发恢复 */ triggerRecovery(): void { if (this.config.enableAutoRecovery && this.recoveryCallback) { this.startRecovery(); } } /** * 停止自动恢复 */ stopRecovery(): void { if (this.recoveryTimer) { this.recoveryTimer.stop(); this.recoveryTimer = undefined; } this.recoveryAttempts = 0; } /** * 设置事件处理器 */ override on(event: K, handler: ConnectionStateManagerEvents[K]): this { this.eventHandlers[event] = handler; return super.on(event, handler as any); } /** * 移除事件处理器 */ override off(event: K): this { delete this.eventHandlers[event]; return super.off(event, this.eventHandlers[event] as any); } /** * 更新配置 */ updateConfig(newConfig: Partial): void { Object.assign(this.config, newConfig); this.logger.info('连接状态管理器配置已更新:', newConfig); } /** * 销毁管理器 */ destroy(): void { this.stopRecovery(); this.clearAllStateTimeouts(); this.removeAllListeners(); } /** * 初始化默认转换规则 */ private initializeDefaultTransitionRules(): void { // 连接尝试 this.addTransitionRule({ from: ConnectionState.Disconnected, to: ConnectionState.Connecting, action: () => this.stats.connectionAttempts++ }); // 连接成功 this.addTransitionRule({ from: ConnectionState.Connecting, to: ConnectionState.Connected, action: () => { this.stats.successfulConnections++; this.recoveryAttempts = 0; // 重置恢复计数 } }); // 连接失败 this.addTransitionRule({ from: ConnectionState.Connecting, to: ConnectionState.Failed, action: () => this.stats.failedConnections++ }); // 重连尝试 this.addTransitionRule({ from: ConnectionState.Failed, to: ConnectionState.Reconnecting, action: () => this.stats.connectionAttempts++ }); // 重连成功 this.addTransitionRule({ from: ConnectionState.Reconnecting, to: ConnectionState.Connected, action: () => { this.stats.successfulConnections++; this.recoveryAttempts = 0; } }); } /** * 检查默认的有效转换 */ private isDefaultValidTransition(from: ConnectionState, to: ConnectionState): boolean { const validTransitions: Record = { [ConnectionState.Disconnected]: [ConnectionState.Connecting], [ConnectionState.Connecting]: [ConnectionState.Connected, ConnectionState.Failed, ConnectionState.Disconnected], [ConnectionState.Connected]: [ConnectionState.Disconnected, ConnectionState.Failed, ConnectionState.Reconnecting], [ConnectionState.Reconnecting]: [ConnectionState.Connected, ConnectionState.Failed, ConnectionState.Disconnected], [ConnectionState.Failed]: [ConnectionState.Reconnecting, ConnectionState.Connecting, ConnectionState.Disconnected] }; return validTransitions[from]?.includes(to) || false; } /** * 更新状态历史 */ private updateStateHistory(state: ConnectionState, duration: number, reason?: string, metadata?: Record): void { const entry: StateHistoryEntry = { state, timestamp: this.stateStartTime, duration, reason, metadata }; this.stateHistory.push(entry); // 限制历史记录数量 if (this.stateHistory.length > 100) { this.stateHistory.shift(); } // 更新状态持续时间统计 this.stats.stateDurations[state].push(duration); if (this.stats.stateDurations[state].length > 50) { this.stats.stateDurations[state].shift(); } // 计算平均持续时间 const durations = this.stats.stateDurations[state]; this.stats.averageStateDurations[state] = durations.reduce((sum, d) => sum + d, 0) / durations.length; } /** * 更新连接统计 */ private updateConnectionStats(from: ConnectionState, to: ConnectionState): void { const now = Date.now(); const duration = now - this.stateStartTime; // 更新在线/离线时间 if (from === ConnectionState.Connected) { this.stats.totalUptime += duration; } else if (this.isConnected()) { // 进入连接状态 } if (this.isDisconnected() && !this.wasDisconnected(from)) { // 进入断开状态,开始计算离线时间 } else if (!this.isDisconnected() && this.wasDisconnected(from)) { // 离开断开状态 this.stats.totalDowntime += duration; } } /** * 检查之前是否为断开状态 */ private wasDisconnected(state: ConnectionState): boolean { return state === ConnectionState.Disconnected || state === ConnectionState.Failed; } /** * 设置状态超时定时器 */ private setStateTimeout(state: ConnectionState): void { if (this.config.stateTimeout <= 0) { return; } const timeout = NetworkTimerManager.schedule( this.config.stateTimeout / 1000, // 转为秒 false, // 不重复 this, () => { const duration = this.getCurrentStateDuration(); this.logger.warn(`状态超时: ${state}, 持续时间: ${duration}ms`); this.eventHandlers.stateTimeout?.(state, duration); } ); this.stateTimeouts.set(state, timeout); } /** * 清理状态超时定时器 */ private clearStateTimeout(state: ConnectionState): void { const timeout = this.stateTimeouts.get(state); if (timeout) { timeout.stop(); this.stateTimeouts.delete(state); } } /** * 清理所有状态超时定时器 */ private clearAllStateTimeouts(): void { for (const timeout of this.stateTimeouts.values()) { timeout.stop(); } this.stateTimeouts.clear(); } /** * 处理自动恢复逻辑 */ private handleAutoRecovery(newState: ConnectionState): void { if (!this.config.enableAutoRecovery) { return; } // 检查是否需要开始恢复 if (newState === ConnectionState.Failed || newState === ConnectionState.Disconnected) { if (this.previousState === ConnectionState.Connected || this.previousState === ConnectionState.Connecting) { this.startRecovery(); } } } /** * 开始恢复过程 */ private startRecovery(): void { if (this.recoveryAttempts >= this.config.maxRecoveryAttempts) { this.logger.warn(`已达到最大恢复尝试次数: ${this.config.maxRecoveryAttempts}`); this.eventHandlers.recoveryFailed?.(true); return; } if (!this.recoveryCallback) { this.logger.error('恢复回调未设置'); return; } this.recoveryAttempts++; this.logger.info(`开始自动恢复 (第 ${this.recoveryAttempts} 次)`); this.eventHandlers.recoveryStarted?.(this.recoveryAttempts); this.recoveryTimer = NetworkTimerManager.schedule( this.config.recoveryTimeout / 1000, // 转为秒 false, // 不重复 this, async () => { try { await this.recoveryCallback!(); this.eventHandlers.recoverySucceeded?.(); } catch (error) { this.logger.error(`自动恢复失败 (第 ${this.recoveryAttempts} 次):`, error); this.eventHandlers.recoveryFailed?.(false); // 继续尝试恢复 this.startRecovery(); } } ); } /** * 更新当前统计信息 */ private updateCurrentStats(): void { const now = Date.now(); const currentDuration = now - this.stateStartTime; if (this.currentState === ConnectionState.Connected) { this.stats.totalUptime += currentDuration - (this.stats.totalUptime > 0 ? 0 : currentDuration); } } /** * 获取状态可读名称 */ getStateDisplayName(state?: ConnectionState): string { const stateNames: Record = { [ConnectionState.Disconnected]: '已断开', [ConnectionState.Connecting]: '连接中', [ConnectionState.Connected]: '已连接', [ConnectionState.Reconnecting]: '重连中', [ConnectionState.Failed]: '连接失败' }; return stateNames[state || this.currentState]; } /** * 获取连接质量评级 */ getConnectionQuality(): 'excellent' | 'good' | 'fair' | 'poor' { const successRate = this.stats.connectionAttempts > 0 ? this.stats.successfulConnections / this.stats.connectionAttempts : 0; const averageConnectedTime = this.stats.averageStateDurations[ConnectionState.Connected]; if (successRate > 0.9 && averageConnectedTime > 60000) { // 成功率>90%且平均连接时间>1分钟 return 'excellent'; } else if (successRate > 0.7 && averageConnectedTime > 30000) { return 'good'; } else if (successRate > 0.5 && averageConnectedTime > 10000) { return 'fair'; } else { return 'poor'; } } }