extends Node class_name NetworkManager ## 网络管理器 ## 负责管理客户端与服务器的 WebSocket 连接 # 信号定义 signal connected_to_server() signal disconnected_from_server() signal connection_error(error: String) signal message_received(message: Dictionary) # 安全管理器 var security_manager: SecurityManager var rate_limiter: RateLimiter # WebSocket 客户端 var _client: WebSocketPeer = null var _server_url: String = "ws://localhost:8080" var _is_connected: bool = false # 重连相关 var _reconnect_attempts: int = 0 var _max_reconnect_attempts: int = 5 var _reconnect_delay: float = 1.0 var _reconnect_timer: float = 0.0 var _should_reconnect: bool = false # 连接超时相关 var _connection_timeout: float = 10.0 var _connection_timer: float = 0.0 var _is_connecting: bool = false func _ready(): """初始化网络管理器""" # 使用默认网络设置(避免GameConfig依赖) _max_reconnect_attempts = 3 _reconnect_delay = 1.0 _connection_timeout = 10.0 # 初始化安全组件 security_manager = SecurityManager.new() add_child(security_manager) rate_limiter = RateLimiter.new() add_child(rate_limiter) print("[NETWORK] NetworkManager initialized") func connect_to_server(url: String = "") -> void: """连接到服务器""" if not url.is_empty(): _server_url = url print("[NETWORK] Connecting to server: ", _server_url) # 如果已经在连接中,先断开 if _is_connecting: disconnect_from_server() _client = WebSocketPeer.new() var err = _client.connect_to_url(_server_url) if err != OK: var error_msg = "连接失败: " + str(err) print("[NETWORK] Failed to connect: ", err) connection_error.emit(error_msg) return # 开始连接超时计时 _is_connecting = true _connection_timer = _connection_timeout print("[NETWORK] Connection initiated (timeout: ", _connection_timeout, "s)") func disconnect_from_server() -> void: """断开服务器连接""" if _client: _client.close() _client = null _is_connected = false _is_connecting = false _connection_timer = 0.0 print("Disconnected from server") disconnected_from_server.emit() func send_message(message: Dictionary) -> void: """发送消息到服务器(使用消息协议)""" if not _is_connected or not _client: print("Cannot send message: not connected") return # 速率限制检查 var client_id = "local_client" # 本地客户端标识 if not rate_limiter.is_message_allowed(client_id): print("[WARNING] [NETWORK] Message blocked by rate limiter") return # 安全验证消息格式 if not SecurityManager.validate_message_format(message): print("[ERROR] [NETWORK] Invalid message format blocked: ", message.get("type", "unknown")) return # 使用 MessageProtocol 序列化 var json_string = MessageProtocol.serialize(message) _client.send_text(json_string) print("Sent message: ", message.get("type", "unknown")) func send_typed_message(type: MessageProtocol.MessageType, data: Dictionary = {}) -> void: """发送指定类型的消息""" var message = MessageProtocol.create_message(type, data) send_message(message) func is_server_connected() -> bool: """检查是否已连接到服务器""" return _is_connected func _process(delta): """处理网络消息和重连逻辑""" # 处理重连计时器 if _should_reconnect and _reconnect_timer > 0: _reconnect_timer -= delta if _reconnect_timer <= 0: _attempt_reconnect() # 处理连接超时 if _is_connecting and _connection_timer > 0: _connection_timer -= delta if _connection_timer <= 0: _handle_connection_timeout() return if not _client: return _client.poll() var state = _client.get_ready_state() # 检查连接状态 if state == WebSocketPeer.STATE_OPEN: if not _is_connected: _is_connected = true _is_connecting = false # 连接成功,停止超时计时 _connection_timer = 0.0 _reconnect_attempts = 0 # 重置重连计数 _should_reconnect = false print("Connected to server!") connected_to_server.emit() # 接收消息 while _client.get_available_packet_count() > 0: var packet = _client.get_packet() var json_string = packet.get_string_from_utf8() # 检查消息长度(防止DoS攻击) if json_string.length() > 10000: # 10KB限制 print("[ERROR] [NETWORK] Message too large, potential DoS attack. Size: ", json_string.length()) continue # 使用 MessageProtocol 反序列化 var message = MessageProtocol.deserialize(json_string) if not message.is_empty(): # 验证消息格式(基础验证) if MessageProtocol.validate_message(message): # 安全验证消息格式(增强验证) if SecurityManager.validate_message_format(message): print("Received message: ", message.get("type", "unknown")) message_received.emit(message) else: print("[ERROR] [NETWORK] Security validation failed for message: ", message.get("type", "unknown")) else: print("[ERROR] [NETWORK] Invalid message format: ", json_string) else: print("[ERROR] [NETWORK] Failed to parse message: ", json_string) elif state == WebSocketPeer.STATE_CLOSING: pass elif state == WebSocketPeer.STATE_CLOSED: if _is_connected: _is_connected = false print("Connection closed") disconnected_from_server.emit() # 触发重连 _trigger_reconnect() elif _is_connecting: # 连接过程中关闭,可能是连接失败 _handle_connection_failure() _client = null func _trigger_reconnect() -> void: """触发重连逻辑""" if _reconnect_attempts < _max_reconnect_attempts: _should_reconnect = true # 指数退避:1秒、2秒、4秒 _reconnect_timer = _reconnect_delay * pow(2, _reconnect_attempts) print("Will attempt reconnect in ", _reconnect_timer, " seconds (attempt ", _reconnect_attempts + 1, "/", _max_reconnect_attempts, ")") else: print("Max reconnect attempts reached") connection_error.emit("Failed to reconnect after " + str(_max_reconnect_attempts) + " attempts") func _attempt_reconnect() -> void: """尝试重新连接""" _reconnect_attempts += 1 print("Attempting to reconnect... (attempt ", _reconnect_attempts, "/", _max_reconnect_attempts, ")") connect_to_server() func reset_reconnect() -> void: """重置重连状态""" _reconnect_attempts = 0 _should_reconnect = false _reconnect_timer = 0.0 func _handle_connection_timeout() -> void: """处理连接超时""" print("[ERROR] [NETWORK] Connection timeout after ", _connection_timeout, " seconds") _is_connecting = false _connection_timer = 0.0 # 关闭WebSocketPeer连接 if _client: _client.close() _client = null connection_error.emit("连接超时:无法连接到服务器,请检查服务器是否启动") func _handle_connection_failure() -> void: """处理连接失败""" print("[ERROR] [NETWORK] Connection failed during handshake") _is_connecting = false _connection_timer = 0.0 connection_error.emit("连接失败:服务器拒绝连接或服务器未启动") func set_connection_timeout(timeout: float) -> void: """设置连接超时时间""" _connection_timeout = timeout func get_connection_timeout() -> float: """获取连接超时时间""" return _connection_timeout