forked from datawhale/whale-town-front
新的目录结构: 01-项目入门/ # 新人必读,项目基础 02-开发规范/ # 编码标准和规范 03-技术实现/ # 具体开发指导 04-高级开发/ # 进阶开发技巧 05-部署运维/ # 发布和部署 06-功能模块/ # 特定功能文档 新增导航文档: - docs/README.md - 完整的文档导航和使用指南 - 各目录下的README.md - 分类说明和使用指导 优化效果: - 开发者可以按阶段快速定位需要的文档 - 新人有清晰的学习路径 - 不同角色有针对性的文档推荐 - 提供了问题导向的快速查找功能
362 lines
11 KiB
Markdown
362 lines
11 KiB
Markdown
# NetworkManager 设置指南
|
||
|
||
## 概述
|
||
|
||
NetworkManager 是一个统一的网络请求管理器,提供了简洁的API接口和统一的错误处理机制。配合 ResponseHandler,可以大大简化网络请求的处理逻辑。
|
||
|
||
## 🚀 快速设置
|
||
|
||
### 1. 设置AutoLoad
|
||
|
||
在Godot编辑器中:
|
||
|
||
1. 打开 `Project` → `Project Settings`
|
||
2. 切换到 `AutoLoad` 标签
|
||
3. 添加新的AutoLoad:
|
||
- **Path**: `res://core/managers/NetworkManager.gd`
|
||
- **Name**: `NetworkManager`
|
||
- **Singleton**: ✅ 勾选
|
||
|
||
### 2. 项目设置文件配置
|
||
|
||
在 `project.godot` 文件中会自动添加:
|
||
|
||
```ini
|
||
[autoload]
|
||
|
||
NetworkManager="*res://core/managers/NetworkManager.gd"
|
||
```
|
||
|
||
### 3. 验证设置
|
||
|
||
在任何脚本中可以直接使用:
|
||
|
||
```gdscript
|
||
func _ready():
|
||
# 直接访问全局单例
|
||
var request_id = NetworkManager.login("username", "password", callback)
|
||
print("请求ID: ", request_id)
|
||
```
|
||
|
||
## 📚 使用方法
|
||
|
||
### 基本用法
|
||
|
||
```gdscript
|
||
# 1. 简单的GET请求
|
||
var request_id = NetworkManager.get_app_status(func(success, data, error_info):
|
||
if success:
|
||
print("应用状态: ", data)
|
||
else:
|
||
print("获取状态失败: ", error_info)
|
||
)
|
||
|
||
# 2. 用户登录
|
||
NetworkManager.login("username", "password", func(success, data, error_info):
|
||
if success:
|
||
print("登录成功: ", data.data.user.username)
|
||
else:
|
||
print("登录失败: ", error_info.message)
|
||
)
|
||
|
||
# 3. 发送验证码
|
||
NetworkManager.send_email_verification("test@example.com", func(success, data, error_info):
|
||
if success:
|
||
print("验证码已发送")
|
||
else:
|
||
print("发送失败: ", error_info.message)
|
||
)
|
||
```
|
||
|
||
### 配合ResponseHandler使用
|
||
|
||
```gdscript
|
||
# 在回调函数中使用ResponseHandler处理响应
|
||
func _on_login_response(success: bool, data: Dictionary, error_info: Dictionary):
|
||
# 使用ResponseHandler统一处理
|
||
var result = ResponseHandler.handle_login_response(success, data, error_info)
|
||
|
||
# 显示Toast消息
|
||
show_toast(result.message, result.success)
|
||
|
||
# 执行自定义动作
|
||
if result.custom_action.is_valid():
|
||
result.custom_action.call()
|
||
|
||
# 处理成功情况
|
||
if result.success:
|
||
# 登录成功的处理逻辑
|
||
login_success.emit(username)
|
||
```
|
||
|
||
### 全局事件监听
|
||
|
||
```gdscript
|
||
func _ready():
|
||
# 监听全局网络事件
|
||
NetworkManager.request_completed.connect(_on_global_request_completed)
|
||
NetworkManager.request_failed.connect(_on_global_request_failed)
|
||
|
||
func _on_global_request_completed(request_id: String, success: bool, data: Dictionary):
|
||
print("全局请求完成: ", request_id)
|
||
# 可以在这里隐藏全局加载指示器
|
||
|
||
func _on_global_request_failed(request_id: String, error_type: String, message: String):
|
||
print("全局请求失败: ", request_id, " - ", message)
|
||
# 可以在这里显示全局错误提示
|
||
```
|
||
|
||
## 🔧 高级功能
|
||
|
||
### 请求管理
|
||
|
||
```gdscript
|
||
# 取消特定请求
|
||
var request_id = NetworkManager.login("user", "pass", callback)
|
||
NetworkManager.cancel_request(request_id)
|
||
|
||
# 取消所有请求
|
||
NetworkManager.cancel_all_requests()
|
||
|
||
# 检查请求状态
|
||
if NetworkManager.is_request_active(request_id):
|
||
print("请求仍在进行中")
|
||
|
||
# 获取活动请求数量
|
||
print("当前活动请求: ", NetworkManager.get_active_request_count())
|
||
```
|
||
|
||
### 自定义请求
|
||
|
||
```gdscript
|
||
# 发送自定义POST请求
|
||
var custom_data = {
|
||
"custom_field": "custom_value"
|
||
}
|
||
var request_id = NetworkManager.post_request("/custom/endpoint", custom_data, func(success, data, error_info):
|
||
print("自定义请求完成")
|
||
)
|
||
|
||
# 发送自定义GET请求
|
||
NetworkManager.get_request("/custom/data", func(success, data, error_info):
|
||
print("获取自定义数据")
|
||
)
|
||
```
|
||
|
||
## 📋 API接口列表
|
||
|
||
### 认证相关
|
||
|
||
| 方法 | 参数 | 说明 |
|
||
|------|------|------|
|
||
| `login(identifier, password, callback)` | 用户标识符、密码、回调函数 | 用户登录 |
|
||
| `verification_code_login(identifier, code, callback)` | 用户标识符、验证码、回调函数 | 验证码登录 |
|
||
| `send_login_verification_code(identifier, callback)` | 用户标识符、回调函数 | 发送登录验证码 |
|
||
| `register(username, password, nickname, email, code, callback)` | 注册信息、回调函数 | 用户注册 |
|
||
| `send_email_verification(email, callback)` | 邮箱、回调函数 | 发送邮箱验证码 |
|
||
| `verify_email(email, code, callback)` | 邮箱、验证码、回调函数 | 验证邮箱 |
|
||
|
||
### 通用请求
|
||
|
||
| 方法 | 参数 | 说明 |
|
||
|------|------|------|
|
||
| `get_request(endpoint, callback, timeout)` | 端点、回调函数、超时时间 | GET请求 |
|
||
| `post_request(endpoint, data, callback, timeout)` | 端点、数据、回调函数、超时时间 | POST请求 |
|
||
| `put_request(endpoint, data, callback, timeout)` | 端点、数据、回调函数、超时时间 | PUT请求 |
|
||
| `delete_request(endpoint, callback, timeout)` | 端点、回调函数、超时时间 | DELETE请求 |
|
||
|
||
### 请求管理
|
||
|
||
| 方法 | 参数 | 说明 |
|
||
|------|------|------|
|
||
| `cancel_request(request_id)` | 请求ID | 取消特定请求 |
|
||
| `cancel_all_requests()` | 无 | 取消所有请求 |
|
||
| `is_request_active(request_id)` | 请求ID | 检查请求是否活动 |
|
||
| `get_active_request_count()` | 无 | 获取活动请求数量 |
|
||
| `get_request_info(request_id)` | 请求ID | 获取请求详细信息 |
|
||
|
||
## 🎯 ResponseHandler 使用
|
||
|
||
### 支持的响应类型
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `handle_login_response()` | 处理登录响应 |
|
||
| `handle_verification_code_login_response()` | 处理验证码登录响应 |
|
||
| `handle_send_verification_code_response()` | 处理发送验证码响应 |
|
||
| `handle_send_login_code_response()` | 处理发送登录验证码响应 |
|
||
| `handle_register_response()` | 处理注册响应 |
|
||
| `handle_verify_email_response()` | 处理邮箱验证响应 |
|
||
| `handle_network_test_response()` | 处理网络测试响应 |
|
||
| `handle_response(operation_type, ...)` | 通用响应处理 |
|
||
|
||
### ResponseResult 结构
|
||
|
||
```gdscript
|
||
class ResponseResult:
|
||
var success: bool # 是否成功
|
||
var message: String # 显示消息
|
||
var toast_type: String # Toast类型 ("success" 或 "error")
|
||
var data: Dictionary # 响应数据
|
||
var should_show_toast: bool # 是否显示Toast
|
||
var custom_action: Callable # 自定义动作
|
||
```
|
||
|
||
## 🔄 迁移指南
|
||
|
||
### 从旧版AuthScene迁移
|
||
|
||
#### 旧代码:
|
||
```gdscript
|
||
func send_login_request(username: String, password: String):
|
||
var url = API_BASE_URL + "/auth/login"
|
||
var headers = ["Content-Type: application/json"]
|
||
var body = JSON.stringify({
|
||
"username": username,
|
||
"password": password
|
||
})
|
||
|
||
current_request_type = "login"
|
||
|
||
var error = http_request.request(url, headers, HTTPClient.METHOD_POST, body)
|
||
if error != OK:
|
||
show_toast('网络请求失败', false)
|
||
restore_button(login_btn, "密码登录")
|
||
current_request_type = ""
|
||
```
|
||
|
||
#### 新代码:
|
||
```gdscript
|
||
func send_login_request(username: String, password: String):
|
||
NetworkManager.login(username, password, _on_login_response)
|
||
|
||
func _on_login_response(success: bool, data: Dictionary, error_info: Dictionary):
|
||
var result = ResponseHandler.handle_login_response(success, data, error_info)
|
||
show_toast(result.message, result.success)
|
||
|
||
if result.success:
|
||
login_success.emit(username)
|
||
```
|
||
|
||
### 迁移步骤
|
||
|
||
1. **设置AutoLoad**:按照上述步骤设置NetworkManager为AutoLoad
|
||
2. **替换请求方法**:将直接的HTTP请求替换为NetworkManager调用
|
||
3. **统一响应处理**:使用ResponseHandler处理所有响应
|
||
4. **移除重复代码**:删除重复的错误处理和请求构建代码
|
||
5. **测试功能**:确保所有功能正常工作
|
||
|
||
## 🧪 测试
|
||
|
||
### 单元测试示例
|
||
|
||
```gdscript
|
||
extends GutTest
|
||
|
||
func test_network_manager_login():
|
||
var network_manager = NetworkManager.new()
|
||
var callback_called = false
|
||
var callback_success = false
|
||
|
||
var callback = func(success, data, error_info):
|
||
callback_called = true
|
||
callback_success = success
|
||
|
||
var request_id = network_manager.login("testuser", "password", callback)
|
||
|
||
assert_ne(request_id, "", "应该返回有效的请求ID")
|
||
|
||
# 等待请求完成
|
||
await get_tree().create_timer(2.0).timeout
|
||
|
||
assert_true(callback_called, "回调函数应该被调用")
|
||
```
|
||
|
||
### 集成测试
|
||
|
||
```gdscript
|
||
func test_complete_login_flow():
|
||
# 1. 发送登录验证码
|
||
var code_sent = false
|
||
NetworkManager.send_login_verification_code("test@example.com", func(success, data, error_info):
|
||
code_sent = success
|
||
)
|
||
|
||
await get_tree().create_timer(1.0).timeout
|
||
assert_true(code_sent, "验证码应该发送成功")
|
||
|
||
# 2. 使用验证码登录
|
||
var login_success = false
|
||
NetworkManager.verification_code_login("test@example.com", "123456", func(success, data, error_info):
|
||
login_success = success
|
||
)
|
||
|
||
await get_tree().create_timer(1.0).timeout
|
||
assert_true(login_success, "验证码登录应该成功")
|
||
```
|
||
|
||
## 🔍 调试
|
||
|
||
### 启用详细日志
|
||
|
||
在NetworkManager中,所有请求都会输出详细的调试信息:
|
||
|
||
```
|
||
=== 发送网络请求 ===
|
||
请求ID: req_1
|
||
URL: https://whaletownend.xinghangee.icu/auth/login
|
||
方法: POST
|
||
Headers: ["Content-Type: application/json"]
|
||
Body: {"username":"testuser","password":"password123"}
|
||
发送结果: 0
|
||
|
||
=== 网络请求完成 ===
|
||
请求ID: req_1
|
||
结果: 0
|
||
状态码: 200
|
||
响应头: ["content-type: application/json"]
|
||
响应体长度: 156 字节
|
||
响应内容: {"success":true,"data":{"user":{"username":"testuser"}}}
|
||
```
|
||
|
||
### 常见问题
|
||
|
||
1. **请求ID为空**:检查NetworkManager是否正确设置为AutoLoad
|
||
2. **回调未调用**:检查网络连接和API地址是否正确
|
||
3. **解析错误**:检查服务器返回的JSON格式是否正确
|
||
|
||
## 📈 性能优化
|
||
|
||
### 请求池管理
|
||
|
||
NetworkManager自动管理请求资源:
|
||
- 自动清理完成的请求
|
||
- 防止内存泄漏
|
||
- 支持请求取消
|
||
|
||
### 最佳实践
|
||
|
||
1. **及时取消不需要的请求**
|
||
2. **使用合适的超时时间**
|
||
3. **避免同时发送大量请求**
|
||
4. **在场景切换时取消活动请求**
|
||
|
||
```gdscript
|
||
func _exit_tree():
|
||
# 场景退出时取消所有请求
|
||
NetworkManager.cancel_all_requests()
|
||
```
|
||
|
||
## 🎉 总结
|
||
|
||
使用NetworkManager和ResponseHandler的优势:
|
||
|
||
- ✅ **代码简洁**:一行代码发送请求
|
||
- ✅ **统一处理**:所有错误情况统一处理
|
||
- ✅ **易于维护**:网络逻辑与UI逻辑分离
|
||
- ✅ **功能强大**:支持请求管理、超时、取消等
|
||
- ✅ **调试友好**:详细的日志和错误信息
|
||
- ✅ **类型安全**:明确的回调参数类型
|
||
- ✅ **可扩展**:易于添加新的API接口
|
||
|
||
通过这套统一的网络管理系统,你的项目将拥有更好的代码结构和更强的可维护性! |