Files
rougelike-demo/client/assets/scripts/Framework/Net/NetManager.ts
2025-12-14 22:39:43 +08:00

308 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NetConfig, DefaultNetConfig } from './NetConfig';
import { NetEvent } from './NetEvent';
import { PlatformAdapter, ClientConfig } from './PlatformAdapter';
/**
* 网络管理器单例
* 负责管理网络连接和消息通信
*/
export class NetManager {
private static _instance: NetManager | null = null;
/** TSRPC Client 实例 (HttpClient) */
private _client: any = 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() {}
/**
* 获取单例实例
*/
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] Platform:', PlatformAdapter.getPlatformInfo());
}
/**
* 连接服务器
*/
async connect(): Promise<boolean> {
try {
console.log('[NetManager] Connecting to server:', this._config.serverUrl);
// 创建客户端配置
const clientConfig: ClientConfig = {
server: this._config.serverUrl,
json: true,
timeout: this._config.timeout
};
// 根据平台创建对应的客户端
this._client = PlatformAdapter.createClient(clientConfig);
// HttpClient 不需要显式连接,创建即可使用
// 如果未来需要 WebSocket 支持,可以在这里添加 connect() 调用
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) {
this.scheduleReconnect();
}
return false;
}
}
/**
* 断开连接
*/
disconnect(): void {
if (!this._isConnected) {
return;
}
// HttpClient 无需显式断开连接
// 如果使用 WebSocket可以在这里调用 disconnect()
this._isConnected = false;
this._client = null;
if(this._reconnectTimer){
this._reconnectTimer = null;
}
// TODO: 调用客户端的断开连接方法
if (this._client && typeof this._client.disconnect === 'function') {
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<Req, Res>(apiName: string, req: Req): Promise<Res | null> {
if (!this._isConnected || !this._client) {
console.error('[NetManager] Not connected');
return null;
}
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;
} 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;
}
}
/**
* 监听消息
* @param msgName 消息名称
* @param handler 处理函数
*/
listenMsg(msgName: string, handler: Function): void {
if (!this._client) {
console.error('[NetManager] Client not initialized');
return;
}
console.log(`[NetManager] Listening message: ${msgName}`);
// TODO: 根据实际的 TSRPC 客户端实现监听消息
if (typeof this._client.listenMsg === 'function') {
this._client.listenMsg(msgName, handler);
}
}
/**
* 发送消息
* @param msgName 消息名称
* @param msg 消息内容
*/
sendMsg(msgName: string, msg: any): void {
if (!this._isConnected || !this._client) {
console.error('[NetManager] Not connected');
return;
}
console.log(`[NetManager] Sending message: ${msgName}`, msg);
// TODO: 根据实际的 TSRPC 客户端实现发送消息
if (typeof this._client.sendMsg === 'function') {
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<void> {
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(): any {
return this._client;
}
}