import { MessagePair, MessagePairRegistry } from '../../App/Msg/MessagePairBase'; import { DefaultNetConfig, NetConfig, NetProtocolType } from './NetConfig'; import { NetEvent } from './NetEvent'; import { ClientConfig, PlatformAdapter } from './PlatformAdapter'; import { INetClient } from './WebSocketClient'; /** * 网络管理器单例 * 负责管理网络连接和消息通信 * 支持 HTTP 和 WebSocket 两种协议 */ export class NetManager { private static _instance: NetManager | null = null; /** TSRPC Client 实例 (HttpClient 或 WsClient) */ private _client: INetClient | null = null; /** 是否已连接 */ private _isConnected: boolean = false; /** 网络配置 */ private _config: NetConfig | null = null; /** 重连计数 */ private _reconnectCount: number = 0; /** 重连定时器 */ private _reconnectTimer: any = null; /** 事件监听器 */ private _eventListeners: Map = new Map(); private constructor() { } /** * 获取单例实例 */ static getInstance(): NetManager { if (!this._instance) { this._instance = new NetManager(); } return this._instance; } /** * 设置服务协议 (必须在 init 之前调用) * @param serviceProto 从 shared 目录导入的协议定义 */ setServiceProto(serviceProto: any): void { PlatformAdapter.setServiceProto(serviceProto); } /** * 初始化网络管理器 * @param config 网络配置 */ init(config: NetConfig): void { this._config = { ...DefaultNetConfig, ...config } as NetConfig; console.log('[NetManager] Initialized with config:', this._config); console.log('[NetManager] Protocol:', this._config.protocolType); console.log('[NetManager] Platform:', PlatformAdapter.getPlatformInfo()); } /** * 连接服务器 */ async connect(): Promise { try { if (!this._config) { console.error('[NetManager] Config not set, please call init() first'); return false; } console.log('[NetManager] Connecting to server:', this._config.serverUrl); // 创建客户端配置 const clientConfig: ClientConfig = { server: this._config.serverUrl, protocolType: this._config.protocolType, json: this._config.json, timeout: this._config.timeout, }; // 根据平台和协议类型创建对应的客户端 this._client = PlatformAdapter.createClient(clientConfig); // 如果是 WebSocket 客户端,需要显式连接 if (this._config.protocolType === NetProtocolType.WebSocket && this._client.connect) { this.emit(NetEvent.Connecting); const result = await this._client.connect(); if (!result.isSucc) { console.error('[NetManager] WebSocket connection failed:', result.errMsg); this.emit(NetEvent.Error, result.errMsg); // 尝试重连 if (this._config.autoReconnect) { this.scheduleReconnect(); } return false; } } this._isConnected = true; this._reconnectCount = 0; this.emit(NetEvent.Connected); console.log('[NetManager] Connected successfully'); return true; } catch (error) { console.error('[NetManager] Connection failed:', error); this.emit(NetEvent.Error, error); // 尝试重连 if (this._config?.autoReconnect) { this.scheduleReconnect(); } return false; } } /** * 断开连接 */ disconnect(): void { if (!this._isConnected || !this._client) { return; } console.log('[NetManager] Disconnecting...'); // 清除重连定时器 if (this._reconnectTimer) { clearTimeout(this._reconnectTimer); this._reconnectTimer = null; } // 如果是 WebSocket 客户端,调用断开连接方法 if (this._client.disconnect) { this._client.disconnect(); } this._isConnected = false; this._client = null; this.emit(NetEvent.Disconnected); console.log('[NetManager] Disconnected'); } /** * 调用 API * @param apiName API 名称 * @param req 请求参数 */ async callApi(apiName: string, req: Req): Promise { if (!this._isConnected || !this._client) { console.error('[NetManager] Not connected'); return null; } try { console.log(`[NetManager] Calling API: ${apiName}`, req); const result = await this._client.callApi(apiName, req); if (result.isSucc) { console.log(`[NetManager] API ${apiName} success:`, result.res); return result.res as Res; } else { console.error(`[NetManager] API ${apiName} failed:`, result.err); return null; } } catch (error) { console.error(`[NetManager] API ${apiName} error:`, error); this.emit(NetEvent.Error, error); return null; } } /** * 监听消息 (仅支持 WebSocket) * @param msgName 消息名称 * @param handler 处理函数 */ listenMsg(msgName: string, handler: Function): void { if (!this._client) { console.error('[NetManager] Client not initialized'); return; } if (!this._client.listenMsg) { console.warn('[NetManager] Message listening not supported for HTTP client'); return; } console.log(`[NetManager] Listening message: ${msgName}`); this._client.listenMsg(msgName, handler); } /** * 取消监听消息 (仅支持 WebSocket) * @param msgName 消息名称 * @param handler 处理函数(可选,不传则取消所有该消息的监听) */ unlistenMsg(msgName: string, handler?: Function): void { if (!this._client) { console.error('[NetManager] Client not initialized'); return; } if (!this._client.unlistenMsg) { console.warn('[NetManager] Message listening not supported for HTTP client'); return; } console.log(`[NetManager] Unlisten message: ${msgName}`); this._client.unlistenMsg(msgName, handler); } /** * 发送消息并等待响应 (基于消息对系统) * @param messagePair 消息对实例 * @param requestData 请求消息内容 * @returns Promise<响应消息> */ async callMsg(messagePair: MessagePair, requestData: TReq): Promise { if (!this._isConnected || !this._client) { console.error('[NetManager] Not connected'); return null; } const requestName = messagePair.requestName; const responseName = messagePair.responseName; // 验证请求消息格式 if (!messagePair.isValidRequest(requestData)) { console.error(`[NetManager] Invalid request data for ${requestName}:`, requestData); return null; } console.log(`[NetManager] Calling message: ${requestName} -> ${responseName}`, requestData); return new Promise((resolve, reject) => { // 创建一次性响应处理器 const responseHandler = (response: TRes) => { // 验证响应消息格式 if (!messagePair.isValidResponse(response)) { return; } // 取消监听 this.unlistenMsg(responseName, responseHandler); // 返回响应 console.log(`[NetManager] Received response for ${requestName}:`, response); resolve(response); }; // 监听响应 this.listenMsg(responseName, responseHandler); // 发送请求消息 this.sendMsg(requestName, requestData); // 设置超时处理 const timeout = this._config?.timeout || 30000; setTimeout(() => { this.unlistenMsg(responseName, responseHandler); console.error(`[NetManager] Request timeout for ${requestName}`); resolve(null); }, timeout); }); } /** * 发送消息 (仅支持 WebSocket) * @param msgName 消息名称 * @param msg 消息内容 */ sendMsg(msgName: string, msg: any): void { if (!this._isConnected || !this._client) { console.error('[NetManager] Not connected'); return; } if (!this._client.sendMsg) { console.warn('[NetManager] Message sending not supported for HTTP client'); return; } console.log(`[NetManager] Sending message: ${msgName}`, msg); this._client.sendMsg(msgName, msg); } /** * 安排重连 */ private scheduleReconnect(): void { if (!this._config) { return; } if (this._reconnectCount >= (this._config.maxReconnectTimes || 5)) { console.error('[NetManager] Max reconnect times reached'); this.emit(NetEvent.ReconnectFailed); return; } this._reconnectCount++; console.log(`[NetManager] Scheduling reconnect (${this._reconnectCount}/${this._config.maxReconnectTimes})...`); this.emit(NetEvent.Reconnecting, this._reconnectCount); this._reconnectTimer = setTimeout(() => { this.reconnect(); }, this._config.reconnectInterval || 3000); } /** * 重新连接 */ private async reconnect(): Promise { console.log('[NetManager] Reconnecting...'); const success = await this.connect(); if (success) { this.emit(NetEvent.ReconnectSuccess); } else if (this._config?.autoReconnect) { this.scheduleReconnect(); } } /** * 监听网络事件 * @param event 事件名称 * @param callback 回调函数 */ on(event: NetEvent, callback: Function): void { if (!this._eventListeners.has(event)) { this._eventListeners.set(event, []); } this._eventListeners.get(event)!.push(callback); } /** * 取消监听网络事件 * @param event 事件名称 * @param callback 回调函数 */ off(event: NetEvent, callback: Function): void { const listeners = this._eventListeners.get(event); if (listeners) { const index = listeners.indexOf(callback); if (index > -1) { listeners.splice(index, 1); } } } /** * 触发事件 * @param event 事件名称 * @param args 事件参数 */ private emit(event: NetEvent, ...args: any[]): void { const listeners = this._eventListeners.get(event); if (listeners) { listeners.forEach(callback => { try { callback(...args); } catch (error) { console.error('[NetManager] Event callback error:', error); } }); } } /** * 获取连接状态 */ get isConnected(): boolean { return this._isConnected; } /** * 获取客户端实例 */ get client(): INetClient | null { return this._client; } /** * 获取协议类型 */ get protocolType(): NetProtocolType | undefined { return this._config?.protocolType; } /** * 判断是否为 WebSocket 连接 */ get isWebSocket(): boolean { return this._config?.protocolType === NetProtocolType.WebSocket; } /** * 判断是否为 HTTP 连接 */ get isHttp(): boolean { return this._config?.protocolType === NetProtocolType.Http; } /** * 获取所有已注册的消息对信息 * @returns 消息对列表 */ getMessagePairs(): { requestName: string; responseName: string }[] { const registry = MessagePairRegistry.getInstance(); return registry.getAllPairs().map(pair => ({ requestName: pair.requestName, responseName: pair.responseName })); } }