304 lines
7.7 KiB
Markdown
304 lines
7.7 KiB
Markdown
|
|
# 网络通信模块 (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 - 网络管理器
|
||
|
|
|
||
|
|
**职责**: 网络连接管理、消息收发、重连机制
|
||
|
|
|
||
|
|
**核心方法**:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
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 HttpClientBrowser` 和 `HttpClient as HttpClientMiniapp`
|
||
|
|
- 自动检测 Cocos 平台类型 (`sys.platform`)
|
||
|
|
- 根据平台实例化对应的客户端
|
||
|
|
|
||
|
|
**核心方法**:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
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 - 网络配置
|
||
|
|
|
||
|
|
**配置接口**:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface NetConfig {
|
||
|
|
serverUrl: string; // 服务器地址
|
||
|
|
timeout?: number; // 超时时间(ms) 默认 30000
|
||
|
|
autoReconnect?: boolean; // 是否自动重连 默认 true
|
||
|
|
reconnectInterval?: number; // 重连间隔(ms) 默认 3000
|
||
|
|
maxReconnectTimes?: number; // 最大重连次数 默认 5
|
||
|
|
}
|
||
|
|
|
||
|
|
// 默认配置
|
||
|
|
const DefaultNetConfig: Partial<NetConfig>;
|
||
|
|
```
|
||
|
|
|
||
|
|
### NetEvent - 网络事件
|
||
|
|
|
||
|
|
**事件类型**:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
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. 基础使用流程
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
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
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
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. 监听服务器消息
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { MsgUserJoin } from '../Shared/protocols/MsgUserJoin';
|
||
|
|
|
||
|
|
// 监听用户加入消息
|
||
|
|
netManager.listenMsg<MsgUserJoin>('UserJoin', (msg) => {
|
||
|
|
console.log('有新用户加入:', msg);
|
||
|
|
});
|
||
|
|
|
||
|
|
// 取消监听
|
||
|
|
netManager.unlistenMsg('UserJoin');
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. 发送消息到服务器
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { MsgChat } from '../Shared/protocols/MsgChat';
|
||
|
|
|
||
|
|
// 发送聊天消息
|
||
|
|
await netManager.sendMsg<MsgChat>('Chat', {
|
||
|
|
content: 'Hello World!'
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔄 协议同步
|
||
|
|
|
||
|
|
### 同步脚本配置
|
||
|
|
|
||
|
|
**文件**: 项目根目录的 `sync-shared.js`
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// 服务端共享目录
|
||
|
|
const serverSharedDir = path.join(__dirname, '../server/src/shared');
|
||
|
|
|
||
|
|
// 客户端目标目录
|
||
|
|
const clientSharedDir = path.join(__dirname, 'assets/scripts/Shared');
|
||
|
|
```
|
||
|
|
|
||
|
|
### 使用步骤
|
||
|
|
|
||
|
|
1. **确保服务端项目位置**: 服务端项目应该在 `../server` 目录
|
||
|
|
2. **运行同步命令**:
|
||
|
|
```bash
|
||
|
|
npm run sync-shared
|
||
|
|
```
|
||
|
|
3. **导入协议**:
|
||
|
|
```typescript
|
||
|
|
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 会自动处理平台差异,无需手动判断
|
||
|
|
|
||
|
|
## 🔍 调试技巧
|
||
|
|
|
||
|
|
### 启用详细日志
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// NetManager 内部已有详细的 console.log
|
||
|
|
// 可以根据日志前缀过滤:
|
||
|
|
// [NetManager] - 网络管理器日志
|
||
|
|
// [PlatformAdapter] - 平台适配器日志
|
||
|
|
```
|
||
|
|
|
||
|
|
### 常见问题
|
||
|
|
|
||
|
|
**问题1**: `协议未设置` 错误
|
||
|
|
```typescript
|
||
|
|
// 解决: 确保在 init 之前调用 setServiceProto
|
||
|
|
netManager.setServiceProto(serviceProto);
|
||
|
|
netManager.init(config);
|
||
|
|
```
|
||
|
|
|
||
|
|
**问题2**: `API 调用返回 null`
|
||
|
|
```typescript
|
||
|
|
// 解决: 检查网络连接状态
|
||
|
|
netManager.on(NetEvent.Connected, async () => {
|
||
|
|
// 在连接成功后再调用 API
|
||
|
|
const result = await netManager.callApi('Login', data);
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
**问题3**: 小程序平台客户端创建失败
|
||
|
|
```typescript
|
||
|
|
// 解决: 确保已安装 tsrpc-miniapp
|
||
|
|
npm install tsrpc-miniapp
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📚 参考资料
|
||
|
|
|
||
|
|
- [TSRPC 官方文档](https://tsrpc.cn/)
|
||
|
|
- [Cocos Creator 官方文档](https://docs.cocos.com/creator/manual/zh/)
|