重构NetManager支持MessagePair,新增TSRPCWsClient。
This commit is contained in:
@@ -1,33 +1,36 @@
|
||||
import { NetConfig, DefaultNetConfig } from './NetConfig';
|
||||
import { MessagePair, MessagePairRegistry } from '../../App/Msg/MessagePairBase';
|
||||
import { DefaultNetConfig, NetConfig, NetProtocolType } from './NetConfig';
|
||||
import { NetEvent } from './NetEvent';
|
||||
import { PlatformAdapter, ClientConfig } from './PlatformAdapter';
|
||||
import { ClientConfig, PlatformAdapter } from './PlatformAdapter';
|
||||
import { INetClient } from './WebSocketClient';
|
||||
|
||||
/**
|
||||
* 网络管理器单例
|
||||
* 负责管理网络连接和消息通信
|
||||
* 支持 HTTP 和 WebSocket 两种协议
|
||||
*/
|
||||
export class NetManager {
|
||||
private static _instance: NetManager | null = null;
|
||||
|
||||
/** TSRPC Client 实例 (HttpClient) */
|
||||
private _client: any = 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<string, Function[]> = new Map();
|
||||
|
||||
private constructor() {}
|
||||
private constructor() { }
|
||||
|
||||
/**
|
||||
* 获取单例实例
|
||||
@@ -58,6 +61,7 @@ export class NetManager {
|
||||
} as NetConfig;
|
||||
|
||||
console.log('[NetManager] Initialized with config:', this._config);
|
||||
console.log('[NetManager] Protocol:', this._config.protocolType);
|
||||
console.log('[NetManager] Platform:', PlatformAdapter.getPlatformInfo());
|
||||
}
|
||||
|
||||
@@ -66,46 +70,56 @@ export class NetManager {
|
||||
*/
|
||||
async connect(): Promise<boolean> {
|
||||
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,
|
||||
json: true,
|
||||
timeout: this._config.timeout
|
||||
protocolType: this._config.protocolType,
|
||||
json: this._config.json,
|
||||
timeout: this._config.timeout,
|
||||
};
|
||||
|
||||
// 根据平台创建对应的客户端
|
||||
// 根据平台和协议类型创建对应的客户端
|
||||
this._client = PlatformAdapter.createClient(clientConfig);
|
||||
|
||||
// HttpClient 不需要显式连接,创建即可使用
|
||||
// 如果未来需要 WebSocket 支持,可以在这里添加 connect() 调用
|
||||
|
||||
// 如果是 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] Client created successfully');
|
||||
|
||||
// client 可能不需要显式连接
|
||||
// 对于 WsClient 需要调用 connect()
|
||||
|
||||
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) {
|
||||
if (this._config?.autoReconnect) {
|
||||
this.scheduleReconnect();
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -114,26 +128,26 @@ export class NetManager {
|
||||
* 断开连接
|
||||
*/
|
||||
disconnect(): void {
|
||||
if (!this._isConnected) {
|
||||
if (!this._isConnected || !this._client) {
|
||||
return;
|
||||
}
|
||||
// HttpClient 无需显式断开连接
|
||||
// 如果使用 WebSocket,可以在这里调用 disconnect()
|
||||
|
||||
this._isConnected = false;
|
||||
this._client = null;
|
||||
if(this._reconnectTimer){
|
||||
|
||||
console.log('[NetManager] Disconnecting...');
|
||||
|
||||
// 清除重连定时器
|
||||
if (this._reconnectTimer) {
|
||||
clearTimeout(this._reconnectTimer);
|
||||
this._reconnectTimer = null;
|
||||
}
|
||||
|
||||
// TODO: 调用客户端的断开连接方法
|
||||
if (this._client && typeof this._client.disconnect === 'function') {
|
||||
// 如果是 WebSocket 客户端,调用断开连接方法
|
||||
if (this._client.disconnect) {
|
||||
this._client.disconnect();
|
||||
}
|
||||
|
||||
this._isConnected = false;
|
||||
this._client = null;
|
||||
|
||||
|
||||
this.emit(NetEvent.Disconnected);
|
||||
console.log('[NetManager] Disconnected');
|
||||
}
|
||||
@@ -151,13 +165,12 @@ export class NetManager {
|
||||
|
||||
try {
|
||||
console.log(`[NetManager] Calling API: ${apiName}`, req);
|
||||
|
||||
// TODO: 根据实际的协议定义调用 API
|
||||
|
||||
const result = await this._client.callApi(apiName, req);
|
||||
|
||||
|
||||
if (result.isSucc) {
|
||||
console.log(`[NetManager] API ${apiName} success:`, result.res);
|
||||
return result.res;
|
||||
return result.res as Res;
|
||||
} else {
|
||||
console.error(`[NetManager] API ${apiName} failed:`, result.err);
|
||||
return null;
|
||||
@@ -170,7 +183,7 @@ export class NetManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听消息
|
||||
* 监听消息 (仅支持 WebSocket)
|
||||
* @param msgName 消息名称
|
||||
* @param handler 处理函数
|
||||
*/
|
||||
@@ -180,16 +193,91 @@ export class NetManager {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[NetManager] Listening message: ${msgName}`);
|
||||
|
||||
// TODO: 根据实际的 TSRPC 客户端实现监听消息
|
||||
if (typeof this._client.listenMsg === 'function') {
|
||||
this._client.listenMsg(msgName, handler);
|
||||
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<TReq, TRes>(messagePair: MessagePair<TReq, TRes>, requestData: TReq): Promise<TRes | null> {
|
||||
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<TRes | null>((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 消息内容
|
||||
*/
|
||||
@@ -199,12 +287,13 @@ export class NetManager {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[NetManager] Sending message: ${msgName}`, msg);
|
||||
|
||||
// TODO: 根据实际的 TSRPC 客户端实现发送消息
|
||||
if (typeof this._client.sendMsg === 'function') {
|
||||
this._client.sendMsg(msgName, msg);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,9 +312,9 @@ export class NetManager {
|
||||
|
||||
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);
|
||||
@@ -236,9 +325,9 @@ export class NetManager {
|
||||
*/
|
||||
private async reconnect(): Promise<void> {
|
||||
console.log('[NetManager] Reconnecting...');
|
||||
|
||||
|
||||
const success = await this.connect();
|
||||
|
||||
|
||||
if (success) {
|
||||
this.emit(NetEvent.ReconnectSuccess);
|
||||
} else if (this._config?.autoReconnect) {
|
||||
@@ -301,7 +390,41 @@ export class NetManager {
|
||||
/**
|
||||
* 获取客户端实例
|
||||
*/
|
||||
get client(): any {
|
||||
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
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user