702 lines
22 KiB
GDScript
702 lines
22 KiB
GDScript
extends Node
|
||
|
||
# ============================================================================
|
||
# NetworkManager.gd - 网络请求管理器
|
||
# ============================================================================
|
||
# 全局单例管理器,统一处理所有HTTP请求
|
||
#
|
||
# 核心职责:
|
||
# - 统一的HTTP请求接口 (GET, POST, PUT, DELETE, PATCH)
|
||
# - 认证相关API封装 (登录、注册、验证码等)
|
||
# - 请求状态管理和错误处理
|
||
# - 支持API v1.1.1规范的响应处理
|
||
#
|
||
# 使用方式:
|
||
# NetworkManager.login("user@example.com", "password", callback)
|
||
# var request_id = NetworkManager.get_request("/api/data", callback)
|
||
#
|
||
# 注意事项:
|
||
# - 作为自动加载单例,全局可访问
|
||
# - 所有请求都是异步的,通过回调函数或信号处理结果
|
||
# - 支持请求超时和取消功能
|
||
# - 自动处理JSON序列化和反序列化
|
||
# ============================================================================
|
||
|
||
# ============ 信号定义 ============
|
||
|
||
# 请求完成信号
|
||
# 参数:
|
||
# request_id: String - 请求唯一标识符
|
||
# success: bool - 请求是否成功
|
||
# data: Dictionary - 响应数据
|
||
signal request_completed(request_id: String, success: bool, data: Dictionary)
|
||
|
||
# 请求失败信号
|
||
# 参数:
|
||
# request_id: String - 请求唯一标识符
|
||
# error_type: String - 错误类型名称
|
||
# message: String - 错误消息
|
||
signal request_failed(request_id: String, error_type: String, message: String)
|
||
|
||
# ============ 常量定义 ============
|
||
|
||
# API基础URL - 所有请求的根地址
|
||
const API_BASE_URL = "https://whaletownend.xinghangee.icu"
|
||
|
||
# 默认请求超时时间(秒)
|
||
const DEFAULT_TIMEOUT = 30.0
|
||
|
||
# ============ 枚举定义 ============
|
||
|
||
# HTTP请求方法枚举
|
||
enum RequestType {
|
||
GET, # 获取数据
|
||
POST, # 创建数据
|
||
PUT, # 更新数据
|
||
DELETE, # 删除数据
|
||
PATCH # 部分更新数据
|
||
}
|
||
|
||
# 错误类型枚举
|
||
# 用于分类不同类型的网络错误
|
||
enum ErrorType {
|
||
NETWORK_ERROR, # 网络连接错误 - 无法连接到服务器
|
||
TIMEOUT_ERROR, # 请求超时 - 服务器响应时间过长
|
||
PARSE_ERROR, # JSON解析错误 - 服务器返回格式错误
|
||
HTTP_ERROR, # HTTP状态码错误 - 4xx, 5xx状态码
|
||
BUSINESS_ERROR # 业务逻辑错误 - API返回的业务错误
|
||
}
|
||
|
||
# ============ 请求信息类 ============
|
||
|
||
# 请求信息封装类
|
||
# 存储单个HTTP请求的所有相关信息
|
||
class RequestInfo:
|
||
var id: String # 请求唯一标识符
|
||
var url: String # 完整的请求URL
|
||
var method: RequestType # HTTP请求方法
|
||
var headers: PackedStringArray # 请求头数组
|
||
var body: String # 请求体内容
|
||
var timeout: float # 超时时间(秒)
|
||
var start_time: float # 请求开始时间戳
|
||
var http_request: HTTPRequest # Godot HTTPRequest节点引用
|
||
var callback: Callable # 完成时的回调函数
|
||
|
||
# 构造函数
|
||
#
|
||
# 参数:
|
||
# request_id: String - 请求唯一标识符
|
||
# request_url: String - 请求URL
|
||
# request_method: RequestType - HTTP方法
|
||
# request_headers: PackedStringArray - 请求头(可选)
|
||
# request_body: String - 请求体(可选)
|
||
# request_timeout: float - 超时时间(可选,默认使用DEFAULT_TIMEOUT)
|
||
func _init(request_id: String, request_url: String, request_method: RequestType,
|
||
request_headers: PackedStringArray = [], request_body: String = "",
|
||
request_timeout: float = DEFAULT_TIMEOUT):
|
||
id = request_id
|
||
url = request_url
|
||
method = request_method
|
||
headers = request_headers
|
||
body = request_body
|
||
timeout = request_timeout
|
||
# 记录请求开始时间(简化版时间戳)
|
||
start_time = Time.get_time_dict_from_system().hour * 3600 + Time.get_time_dict_from_system().minute * 60 + Time.get_time_dict_from_system().second
|
||
|
||
# ============ 成员变量 ============
|
||
|
||
# 活动请求管理
|
||
var active_requests: Dictionary = {} # 存储所有活动请求 {request_id: RequestInfo}
|
||
var request_counter: int = 0 # 请求计数器,用于生成唯一ID
|
||
|
||
# ============ 生命周期方法 ============
|
||
|
||
# 初始化网络管理器
|
||
# 在节点准备就绪时调用
|
||
func _ready():
|
||
print("NetworkManager 已初始化")
|
||
|
||
# ============ 公共API接口 ============
|
||
|
||
# 发送GET请求
|
||
#
|
||
# 参数:
|
||
# endpoint: String - API端点路径(如: "/api/users")
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
# timeout: float - 超时时间(可选,默认30秒)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID,可用于取消请求或跟踪状态
|
||
#
|
||
# 使用示例:
|
||
# var request_id = NetworkManager.get_request("/api/users", my_callback)
|
||
func get_request(endpoint: String, callback: Callable = Callable(), timeout: float = DEFAULT_TIMEOUT) -> String:
|
||
return send_request(endpoint, RequestType.GET, [], "", callback, timeout)
|
||
|
||
# 发送POST请求
|
||
#
|
||
# 参数:
|
||
# endpoint: String - API端点路径
|
||
# data: Dictionary - 要发送的数据(将自动转换为JSON)
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
# timeout: float - 超时时间(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 使用示例:
|
||
# var data = {"name": "张三", "age": 25}
|
||
# var request_id = NetworkManager.post_request("/api/users", data, my_callback)
|
||
func post_request(endpoint: String, data: Dictionary, callback: Callable = Callable(), timeout: float = DEFAULT_TIMEOUT) -> String:
|
||
var body = JSON.stringify(data)
|
||
var headers = ["Content-Type: application/json"]
|
||
return send_request(endpoint, RequestType.POST, headers, body, callback, timeout)
|
||
|
||
# 发送PUT请求
|
||
#
|
||
# 参数:
|
||
# endpoint: String - API端点路径
|
||
# data: Dictionary - 要更新的数据
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
# timeout: float - 超时时间(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
func put_request(endpoint: String, data: Dictionary, callback: Callable = Callable(), timeout: float = DEFAULT_TIMEOUT) -> String:
|
||
var body = JSON.stringify(data)
|
||
var headers = ["Content-Type: application/json"]
|
||
return send_request(endpoint, RequestType.PUT, headers, body, callback, timeout)
|
||
|
||
# 发送DELETE请求
|
||
#
|
||
# 参数:
|
||
# endpoint: String - API端点路径
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
# timeout: float - 超时时间(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
func delete_request(endpoint: String, callback: Callable = Callable(), timeout: float = DEFAULT_TIMEOUT) -> String:
|
||
return send_request(endpoint, RequestType.DELETE, [], "", callback, timeout)
|
||
|
||
# ============ 认证相关API ============
|
||
|
||
# 用户登录
|
||
#
|
||
# 参数:
|
||
# identifier: String - 用户标识符(邮箱或手机号)
|
||
# password: String - 用户密码
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 回调函数签名:
|
||
# func callback(success: bool, data: Dictionary, error_info: Dictionary)
|
||
#
|
||
# 使用示例:
|
||
# NetworkManager.login("user@example.com", "password123", func(success, data, error):
|
||
# if success:
|
||
# print("登录成功: ", data)
|
||
# else:
|
||
# print("登录失败: ", error.message)
|
||
# )
|
||
func login(identifier: String, password: String, callback: Callable = Callable()) -> String:
|
||
var data = {
|
||
"identifier": identifier,
|
||
"password": password
|
||
}
|
||
return post_request("/auth/login", data, callback)
|
||
|
||
# 验证码登录
|
||
#
|
||
# 参数:
|
||
# identifier: String - 用户标识符(邮箱或手机号)
|
||
# verification_code: String - 验证码
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 使用场景:
|
||
# - 用户忘记密码时的替代登录方式
|
||
# - 提供更安全的登录选项
|
||
func verification_code_login(identifier: String, verification_code: String, callback: Callable = Callable()) -> String:
|
||
var data = {
|
||
"identifier": identifier,
|
||
"verification_code": verification_code
|
||
}
|
||
return post_request("/auth/verification-code-login", data, callback)
|
||
|
||
# 发送登录验证码
|
||
#
|
||
# 参数:
|
||
# identifier: String - 用户标识符(邮箱或手机号)
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 功能:
|
||
# - 向已注册用户发送登录验证码
|
||
# - 支持邮箱和手机号
|
||
# - 有频率限制保护
|
||
func send_login_verification_code(identifier: String, callback: Callable = Callable()) -> String:
|
||
var data = {"identifier": identifier}
|
||
return post_request("/auth/send-login-verification-code", data, callback)
|
||
|
||
# 用户注册
|
||
#
|
||
# 参数:
|
||
# username: String - 用户名
|
||
# password: String - 密码
|
||
# nickname: String - 昵称
|
||
# email: String - 邮箱地址(可选)
|
||
# email_verification_code: String - 邮箱验证码(可选)
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 注意事项:
|
||
# - 如果提供邮箱,建议同时提供验证码
|
||
# - 用户名和邮箱必须唯一
|
||
# - 密码需要符合安全要求
|
||
func register(username: String, password: String, nickname: String, email: String = "",
|
||
email_verification_code: String = "", callback: Callable = Callable()) -> String:
|
||
var data = {
|
||
"username": username,
|
||
"password": password,
|
||
"nickname": nickname
|
||
}
|
||
|
||
# 可选参数处理
|
||
if email != "":
|
||
data["email"] = email
|
||
if email_verification_code != "":
|
||
data["email_verification_code"] = email_verification_code
|
||
|
||
return post_request("/auth/register", data, callback)
|
||
|
||
# 发送邮箱验证码
|
||
#
|
||
# 参数:
|
||
# email: String - 邮箱地址
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 功能:
|
||
# - 向指定邮箱发送验证码
|
||
# - 用于注册时的邮箱验证
|
||
# - 支持测试模式(开发环境)
|
||
func send_email_verification(email: String, callback: Callable = Callable()) -> String:
|
||
var data = {"email": email}
|
||
return post_request("/auth/send-email-verification", data, callback)
|
||
|
||
# 验证邮箱
|
||
#
|
||
# 参数:
|
||
# email: String - 邮箱地址
|
||
# verification_code: String - 验证码
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 功能:
|
||
# - 验证邮箱验证码的有效性
|
||
# - 通常在注册流程中使用
|
||
func verify_email(email: String, verification_code: String, callback: Callable = Callable()) -> String:
|
||
var data = {
|
||
"email": email,
|
||
"verification_code": verification_code
|
||
}
|
||
return post_request("/auth/verify-email", data, callback)
|
||
|
||
# 获取应用状态
|
||
#
|
||
# 参数:
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 功能:
|
||
# - 检查API服务器状态
|
||
# - 获取应用基本信息
|
||
# - 用于网络连接测试
|
||
func get_app_status(callback: Callable = Callable()) -> String:
|
||
return get_request("/", callback)
|
||
|
||
# 重新发送邮箱验证码
|
||
#
|
||
# 参数:
|
||
# email: String - 邮箱地址
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 使用场景:
|
||
# - 用户未收到验证码时重新发送
|
||
# - 验证码过期后重新获取
|
||
func resend_email_verification(email: String, callback: Callable = Callable()) -> String:
|
||
var data = {"email": email}
|
||
return post_request("/auth/resend-email-verification", data, callback)
|
||
|
||
# 忘记密码 - 发送重置验证码
|
||
#
|
||
# 参数:
|
||
# identifier: String - 用户标识符(邮箱或手机号)
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 功能:
|
||
# - 向用户发送密码重置验证码
|
||
# - 用于密码找回流程的第一步
|
||
func forgot_password(identifier: String, callback: Callable = Callable()) -> String:
|
||
var data = {"identifier": identifier}
|
||
return post_request("/auth/forgot-password", data, callback)
|
||
|
||
# 重置密码
|
||
#
|
||
# 参数:
|
||
# identifier: String - 用户标识符
|
||
# verification_code: String - 重置验证码
|
||
# new_password: String - 新密码
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 功能:
|
||
# - 使用验证码重置用户密码
|
||
# - 密码找回流程的第二步
|
||
func reset_password(identifier: String, verification_code: String, new_password: String, callback: Callable = Callable()) -> String:
|
||
var data = {
|
||
"identifier": identifier,
|
||
"verification_code": verification_code,
|
||
"new_password": new_password
|
||
}
|
||
return post_request("/auth/reset-password", data, callback)
|
||
|
||
# 修改密码
|
||
#
|
||
# 参数:
|
||
# user_id: String - 用户ID
|
||
# old_password: String - 旧密码
|
||
# new_password: String - 新密码
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 功能:
|
||
# - 已登录用户修改密码
|
||
# - 需要验证旧密码
|
||
func change_password(user_id: String, old_password: String, new_password: String, callback: Callable = Callable()) -> String:
|
||
var data = {
|
||
"user_id": user_id,
|
||
"old_password": old_password,
|
||
"new_password": new_password
|
||
}
|
||
return put_request("/auth/change-password", data, callback)
|
||
|
||
# GitHub OAuth登录
|
||
#
|
||
# 参数:
|
||
# github_id: String - GitHub用户ID
|
||
# username: String - GitHub用户名
|
||
# nickname: String - 显示昵称
|
||
# email: String - GitHub邮箱
|
||
# avatar_url: String - 头像URL(可选)
|
||
# callback: Callable - 完成时的回调函数(可选)
|
||
#
|
||
# 返回值:
|
||
# String - 请求ID
|
||
#
|
||
# 功能:
|
||
# - 通过GitHub账号登录或注册
|
||
# - 支持第三方OAuth认证
|
||
func github_login(github_id: String, username: String, nickname: String, email: String, avatar_url: String = "", callback: Callable = Callable()) -> String:
|
||
var data = {
|
||
"github_id": github_id,
|
||
"username": username,
|
||
"nickname": nickname,
|
||
"email": email
|
||
}
|
||
|
||
# 可选头像URL
|
||
if avatar_url != "":
|
||
data["avatar_url"] = avatar_url
|
||
|
||
return post_request("/auth/github", data, callback)
|
||
|
||
# ============ 核心请求处理 ============
|
||
|
||
# 发送请求的核心方法
|
||
func send_request(endpoint: String, method: RequestType, headers: PackedStringArray,
|
||
body: String, callback: Callable, timeout: float) -> String:
|
||
# 生成请求ID
|
||
request_counter += 1
|
||
var request_id = "req_" + str(request_counter)
|
||
|
||
# 构建完整URL
|
||
var full_url = API_BASE_URL + endpoint
|
||
|
||
# 创建HTTPRequest节点
|
||
var http_request = HTTPRequest.new()
|
||
add_child(http_request)
|
||
|
||
# 设置超时
|
||
http_request.timeout = timeout
|
||
|
||
# 创建请求信息
|
||
var request_info = RequestInfo.new(request_id, full_url, method, headers, body, timeout)
|
||
request_info.http_request = http_request
|
||
request_info.callback = callback
|
||
|
||
# 存储请求信息
|
||
active_requests[request_id] = request_info
|
||
|
||
# 连接信号
|
||
http_request.request_completed.connect(func(result: int, response_code: int, response_headers: PackedStringArray, response_body: PackedByteArray):
|
||
_on_request_completed(request_id, result, response_code, response_headers, response_body)
|
||
)
|
||
|
||
# 发送请求
|
||
var godot_method = _convert_to_godot_method(method)
|
||
var error = http_request.request(full_url, headers, godot_method, body)
|
||
|
||
print("=== 发送网络请求 ===")
|
||
print("请求ID: ", request_id)
|
||
print("URL: ", full_url)
|
||
print("方法: ", RequestType.keys()[method])
|
||
print("Headers: ", headers)
|
||
print("Body: ", body if body.length() < 200 else body.substr(0, 200) + "...")
|
||
print("发送结果: ", error)
|
||
|
||
if error != OK:
|
||
print("请求发送失败,错误代码: ", error)
|
||
_handle_request_error(request_id, ErrorType.NETWORK_ERROR, "网络请求发送失败: " + str(error))
|
||
return ""
|
||
|
||
return request_id
|
||
|
||
# 请求完成回调
|
||
func _on_request_completed(request_id: String, result: int, response_code: int,
|
||
headers: PackedStringArray, body: PackedByteArray):
|
||
print("=== 网络请求完成 ===")
|
||
print("请求ID: ", request_id)
|
||
print("结果: ", result)
|
||
print("状态码: ", response_code)
|
||
print("响应头: ", headers)
|
||
|
||
# 获取请求信息
|
||
if not active_requests.has(request_id):
|
||
print("警告: 未找到请求ID ", request_id)
|
||
return
|
||
|
||
var _request_info = active_requests[request_id]
|
||
var response_text = body.get_string_from_utf8()
|
||
|
||
print("响应体长度: ", body.size(), " 字节")
|
||
print("响应内容: ", response_text if response_text.length() < 500 else response_text.substr(0, 500) + "...")
|
||
|
||
# 处理网络连接失败
|
||
if response_code == 0:
|
||
_handle_request_error(request_id, ErrorType.NETWORK_ERROR, "网络连接失败,请检查网络连接")
|
||
return
|
||
|
||
# 解析JSON响应
|
||
var json = JSON.new()
|
||
var parse_result = json.parse(response_text)
|
||
if parse_result != OK:
|
||
_handle_request_error(request_id, ErrorType.PARSE_ERROR, "服务器响应格式错误")
|
||
return
|
||
|
||
var response_data = json.data
|
||
|
||
# 处理响应
|
||
_handle_response(request_id, response_code, response_data)
|
||
|
||
# 处理响应 - 支持API v1.1.1的状态码
|
||
func _handle_response(request_id: String, response_code: int, data: Dictionary):
|
||
var request_info = active_requests[request_id]
|
||
|
||
# 检查业务成功标志
|
||
var success = data.get("success", true) # 默认true保持向后兼容
|
||
var error_code = data.get("error_code", "")
|
||
var message = data.get("message", "")
|
||
|
||
# 判断请求是否成功
|
||
var is_success = false
|
||
|
||
# HTTP成功状态码且业务成功
|
||
if (response_code >= 200 and response_code < 300) and success:
|
||
is_success = true
|
||
# 特殊情况:206测试模式 - 根据API文档,这是成功的测试模式响应
|
||
elif response_code == 206 and error_code == "TEST_MODE_ONLY":
|
||
is_success = true
|
||
print("🧪 测试模式响应: ", message)
|
||
# 201创建成功
|
||
elif response_code == 201:
|
||
is_success = true
|
||
|
||
if is_success:
|
||
print("✅ 请求成功: ", request_id)
|
||
# 发送成功信号
|
||
request_completed.emit(request_id, true, data)
|
||
|
||
# 调用回调函数
|
||
if request_info.callback.is_valid():
|
||
request_info.callback.call(true, data, {})
|
||
else:
|
||
print("❌ 请求失败: ", request_id, " - HTTP:", response_code, " 错误码:", error_code, " 消息:", message)
|
||
|
||
# 确定错误类型
|
||
var error_type = _determine_error_type(response_code, error_code)
|
||
|
||
# 发送失败信号
|
||
request_failed.emit(request_id, ErrorType.keys()[error_type], message)
|
||
|
||
# 调用回调函数
|
||
if request_info.callback.is_valid():
|
||
var error_info = {
|
||
"response_code": response_code,
|
||
"error_code": error_code,
|
||
"message": message,
|
||
"error_type": error_type
|
||
}
|
||
request_info.callback.call(false, data, error_info)
|
||
|
||
# 清理请求
|
||
_cleanup_request(request_id)
|
||
|
||
# 处理请求错误
|
||
func _handle_request_error(request_id: String, error_type: ErrorType, message: String):
|
||
print("❌ 请求错误: ", request_id, " - ", message)
|
||
|
||
# 发送错误信号
|
||
request_failed.emit(request_id, ErrorType.keys()[error_type], message)
|
||
|
||
# 调用回调函数
|
||
if active_requests.has(request_id):
|
||
var request_info = active_requests[request_id]
|
||
if request_info.callback.is_valid():
|
||
var error_info = {
|
||
"error_type": error_type,
|
||
"message": message
|
||
}
|
||
request_info.callback.call(false, {}, error_info)
|
||
|
||
# 清理请求
|
||
_cleanup_request(request_id)
|
||
|
||
# 确定错误类型 - 支持更多状态码
|
||
func _determine_error_type(response_code: int, error_code: String) -> ErrorType:
|
||
# 根据错误码判断
|
||
match error_code:
|
||
"SERVICE_UNAVAILABLE":
|
||
return ErrorType.BUSINESS_ERROR
|
||
"TOO_MANY_REQUESTS":
|
||
return ErrorType.BUSINESS_ERROR
|
||
"TEST_MODE_ONLY":
|
||
return ErrorType.BUSINESS_ERROR
|
||
"SEND_EMAIL_VERIFICATION_FAILED", "REGISTER_FAILED":
|
||
# 这些可能是409冲突或其他业务错误
|
||
return ErrorType.BUSINESS_ERROR
|
||
_:
|
||
# 根据HTTP状态码判断
|
||
match response_code:
|
||
409: # 资源冲突
|
||
return ErrorType.BUSINESS_ERROR
|
||
206: # 测试模式
|
||
return ErrorType.BUSINESS_ERROR
|
||
429: # 频率限制
|
||
return ErrorType.BUSINESS_ERROR
|
||
_:
|
||
if response_code >= 400 and response_code < 500:
|
||
return ErrorType.HTTP_ERROR
|
||
elif response_code >= 500:
|
||
return ErrorType.HTTP_ERROR
|
||
else:
|
||
return ErrorType.BUSINESS_ERROR
|
||
|
||
# 清理请求资源
|
||
func _cleanup_request(request_id: String):
|
||
if active_requests.has(request_id):
|
||
var request_info = active_requests[request_id]
|
||
|
||
# 移除HTTPRequest节点
|
||
if is_instance_valid(request_info.http_request):
|
||
request_info.http_request.queue_free()
|
||
|
||
# 从活动请求中移除
|
||
active_requests.erase(request_id)
|
||
|
||
print("🧹 清理请求: ", request_id)
|
||
|
||
# 转换请求方法
|
||
func _convert_to_godot_method(method: RequestType) -> HTTPClient.Method:
|
||
match method:
|
||
RequestType.GET:
|
||
return HTTPClient.METHOD_GET
|
||
RequestType.POST:
|
||
return HTTPClient.METHOD_POST
|
||
RequestType.PUT:
|
||
return HTTPClient.METHOD_PUT
|
||
RequestType.DELETE:
|
||
return HTTPClient.METHOD_DELETE
|
||
RequestType.PATCH:
|
||
return HTTPClient.METHOD_PATCH
|
||
_:
|
||
return HTTPClient.METHOD_GET
|
||
|
||
# ============ 工具方法 ============
|
||
|
||
# 取消请求
|
||
func cancel_request(request_id: String) -> bool:
|
||
if active_requests.has(request_id):
|
||
print("🚫 取消请求: ", request_id)
|
||
_cleanup_request(request_id)
|
||
return true
|
||
return false
|
||
|
||
# 取消所有请求
|
||
func cancel_all_requests():
|
||
print("🚫 取消所有请求")
|
||
var request_ids = active_requests.keys()
|
||
for request_id in request_ids:
|
||
cancel_request(request_id)
|
||
|
||
# 获取活动请求数量
|
||
func get_active_request_count() -> int:
|
||
return active_requests.size()
|
||
|
||
# 检查请求是否活动
|
||
func is_request_active(request_id: String) -> bool:
|
||
return active_requests.has(request_id)
|
||
|
||
# 获取请求信息
|
||
func get_request_info(request_id: String) -> Dictionary:
|
||
if active_requests.has(request_id):
|
||
var info = active_requests[request_id]
|
||
return {
|
||
"id": info.id,
|
||
"url": info.url,
|
||
"method": RequestType.keys()[info.method],
|
||
"start_time": info.start_time,
|
||
"timeout": info.timeout
|
||
}
|
||
return {}
|
||
|
||
func _notification(what):
|
||
if what == NOTIFICATION_WM_CLOSE_REQUEST:
|
||
# 应用关闭时取消所有请求
|
||
cancel_all_requests()
|