Files
2025-12-14 22:39:43 +08:00

7.7 KiB

网络通信模块 (Framework/Net)

📋 模块概述

基于 TSRPC 的网络通信层,支持多平台(浏览器、小程序),提供 API 调用和服务器消息监听功能。

🎯 核心特性

  • 跨平台支持(浏览器/小程序)
  • 自动平台检测和适配
  • 服务协议动态配置
  • API 调用和消息监听
  • 自动重连机制
  • 完整的事件系统

📦 依赖包

平台 NPM 包
浏览器 (Web) tsrpc-browser
小程序 (微信/抖音/QQ) tsrpc-miniapp

🗂️ 文件结构

Framework/Net/
├── NetManager.ts         # 网络管理器(核心)
├── PlatformAdapter.ts    # 平台适配器
├── NetConfig.ts          # 网络配置
├── NetEvent.ts           # 网络事件
├── LoginProtocol.ts      # 登录协议(临时)
└── NetExample.ts         # 使用示例

📘 核心类详解

NetManager - 网络管理器

职责: 网络连接管理、消息收发、重连机制

核心方法:

class NetManager {
    // 获取单例
    static getInstance(): NetManager;
    
    // 设置服务协议(必须在 init 之前调用)
    setServiceProto(serviceProto: ServiceProto): void;
    
    // 初始化网络配置
    init(config: NetConfig): void;
    
    // 创建客户端实例并连接
    connect(): Promise<boolean>;
    
    // 断开连接并清理资源
    disconnect(): void;
    
    // 调用 API
    callApi<Req, Res>(apiName: string, req: Req): Promise<Res | null>;
    
    // 监听服务器消息
    listenMsg<T>(msgName: string, handler: (msg: T) => void): void;
    
    // 取消监听服务器消息
    unlistenMsg(msgName: string, handler?: Function): void;
    
    // 发送消息到服务器
    sendMsg<T>(msgName: string, msg: T): Promise<void>;
    
    // 监听网络事件
    on(event: NetEvent, callback: Function): void;
    
    // 取消监听网络事件
    off(event: NetEvent, callback: Function): void;
}

PlatformAdapter - 平台适配器

职责: 根据运行平台创建对应的 TSRPC 客户端

技术实现:

  • 使用别名导入: HttpClient as HttpClientBrowserHttpClient as HttpClientMiniapp
  • 自动检测 Cocos 平台类型 (sys.platform)
  • 根据平台实例化对应的客户端

核心方法:

class PlatformAdapter {
    // 设置服务协议
    static setServiceProto(serviceProto: ServiceProto): void;
    
    // 检测当前运行平台
    static detectPlatform(): string;
    
    // 创建对应平台的客户端实例
    static createClient(config: NetConfig): HttpClient | null;
    
    // 获取当前平台
    static getCurrentPlatform(): string;
    
    // 平台判断
    static isMiniApp(): boolean;
    static isBrowser(): boolean;
    
    // 获取平台详细信息
    static getPlatformInfo(): object;
}

NetConfig - 网络配置

配置接口:

interface NetConfig {
    serverUrl: string;          // 服务器地址
    timeout?: number;            // 超时时间(ms) 默认 30000
    autoReconnect?: boolean;     // 是否自动重连 默认 true
    reconnectInterval?: number;  // 重连间隔(ms) 默认 3000
    maxReconnectTimes?: number;  // 最大重连次数 默认 5
}

// 默认配置
const DefaultNetConfig: Partial<NetConfig>;

NetEvent - 网络事件

事件类型:

enum NetEvent {
    Connected = "net_connected",              // 连接成功
    Disconnected = "net_disconnected",        // 连接断开
    Reconnecting = "net_reconnecting",        // 正在重连
    ReconnectSuccess = "net_reconnect_success", // 重连成功
    ReconnectFailed = "net_reconnect_failed", // 重连失败
    Error = "net_error",                      // 网络错误
    Timeout = "net_timeout"                   // 连接超时
}

📝 使用指南

1. 基础使用流程

import { NetManager } from './Framework/Net/NetManager';
import { NetConfig } from './Framework/Net/NetConfig';
import { NetEvent } from './Framework/Net/NetEvent';
import { serviceProto } from '../Shared/protocols/serviceProto';

// 1. 获取实例并设置协议
const netManager = NetManager.getInstance();
netManager.setServiceProto(serviceProto);  // 必须在 init 之前

// 2. 监听网络事件
netManager.on(NetEvent.Connected, () => {
    console.log('✅ 网络已连接');
});

netManager.on(NetEvent.Disconnected, () => {
    console.log('❌ 网络已断开');
});

netManager.on(NetEvent.Error, (error: any) => {
    console.error('⚠️ 网络错误:', error);
});

// 3. 初始化配置
const config: NetConfig = {
    serverUrl: 'http://localhost:3000',
    timeout: 30000,
    autoReconnect: true,
    reconnectInterval: 3000,
    maxReconnectTimes: 5
};
netManager.init(config);

// 4. 连接服务器
const success = await netManager.connect();
if (success) {
    console.log('✅ 网络初始化成功');
}

2. 调用 API

import { ReqLogin, ResLogin } from '../Shared/protocols/PtlLogin';

// 调用登录 API
const result = await netManager.callApi<ReqLogin, ResLogin>('Login', {
    username: 'testUser',
    password: '123456'
});

if (result) {
    console.log('登录成功:', result);
}

3. 监听服务器消息

import { MsgUserJoin } from '../Shared/protocols/MsgUserJoin';

// 监听用户加入消息
netManager.listenMsg<MsgUserJoin>('UserJoin', (msg) => {
    console.log('有新用户加入:', msg);
});

// 取消监听
netManager.unlistenMsg('UserJoin');

4. 发送消息到服务器

import { MsgChat } from '../Shared/protocols/MsgChat';

// 发送聊天消息
await netManager.sendMsg<MsgChat>('Chat', {
    content: 'Hello World!'
});

🔄 协议同步

同步脚本配置

文件: 项目根目录的 sync-shared.js

// 服务端共享目录
const serverSharedDir = path.join(__dirname, '../server/src/shared');

// 客户端目标目录
const clientSharedDir = path.join(__dirname, 'assets/scripts/Shared');

使用步骤

  1. 确保服务端项目位置: 服务端项目应该在 ../server 目录
  2. 运行同步命令:
    npm run sync-shared
    
  3. 导入协议:
    import { serviceProto } from '../Shared/protocols/serviceProto';
    import { ReqLogin, ResLogin } from '../Shared/protocols/PtlLogin';
    

⚠️ 注意事项

  1. 协议必须先设置: 在调用 init() 之前,必须先调用 setServiceProto()
  2. 连接状态检查: 调用 API 前确保已连接,否则会返回 null
  3. 错误处理: 建议监听 NetEvent.Error 事件处理网络错误
  4. 资源清理: 应用退出时调用 disconnect() 清理资源
  5. 平台兼容: PlatformAdapter 会自动处理平台差异,无需手动判断

🔍 调试技巧

启用详细日志

// NetManager 内部已有详细的 console.log
// 可以根据日志前缀过滤:
// [NetManager] - 网络管理器日志
// [PlatformAdapter] - 平台适配器日志

常见问题

问题1: 协议未设置 错误

// 解决: 确保在 init 之前调用 setServiceProto
netManager.setServiceProto(serviceProto);
netManager.init(config);

问题2: API 调用返回 null

// 解决: 检查网络连接状态
netManager.on(NetEvent.Connected, async () => {
    // 在连接成功后再调用 API
    const result = await netManager.callApi('Login', data);
});

问题3: 小程序平台客户端创建失败

// 解决: 确保已安装 tsrpc-miniapp
npm install tsrpc-miniapp

📚 参考资料