extends Node # Bridge 客户端 - 连接 Godot 和 OpenClaw signal action_received(action: Dictionary) signal state_synced(state: Dictionary) signal connected_to_bridge() signal disconnected_from_bridge() @export var bridge_url: String = "ws://127.0.0.1:8765" @export var reconnect_interval: float = 5.0 @export var auto_connect: bool = false # 默认不自动连接 var socket: WebSocketPeer var is_connected: bool = false var reconnect_timer: float = 0.0 func _ready(): # 作为全局单例 name = "BridgeClient" print("BridgeClient initialized, auto_connect = ", auto_connect) if auto_connect: _connect_to_bridge() func _process(delta): if socket: _socket_poll() elif reconnect_timer > 0: reconnect_timer -= delta if reconnect_timer <= 0: _connect_to_bridge() func _connect_to_bridge(): print("Connecting to OpenClaw Bridge at ", bridge_url) socket = WebSocketPeer.new() var err = socket.connect_to_url(bridge_url) if err != OK: print("Failed to connect: ", err) _schedule_reconnect() return # 设置状态 is_connected = false func _socket_poll(): socket.poll() var state = socket.get_ready_state() match state: WebSocketPeer.STATE_CONNECTING: pass # 正在连接 WebSocketPeer.STATE_OPEN: if not is_connected: is_connected = true print("Connected to OpenClaw Bridge!") emit_signal("connected_to_bridge") _send_hello() # 处理收到的消息 while socket.get_available_packets() > 0: var packet = socket.get_packet() var message_str = packet.get_string_from_utf8() _parse_message(message_str) WebSocketPeer.STATE_CLOSING: pass # 正在关闭 WebSocketPeer.STATE_CLOSED: if is_connected: is_connected = false print("Disconnected from Bridge") emit_signal("disconnected_from_bridge") socket = null _schedule_reconnect() func _schedule_reconnect(): reconnect_timer = reconnect_interval print("Will reconnect in ", reconnect_interval, " seconds...") func _send_hello(): send_command({ "type": "hello", "client": "godot", "agent_id": "val", "timestamp": Time.get_unix_time_from_system() }) func _parse_message(message_str: String): var json = JSON.new() var err = json.parse(message_str) if err != OK: print("Failed to parse JSON: ", message_str) return var message = json.get_data() if typeof(message) != TYPE_DICTIONARY: print("Invalid message format") return var msg_type = message.get("type", "") match msg_type: "action_sequence": # 解析动作序列 var actions = message.get("actions", []) for action in actions: emit_signal("action_received", action) "state_sync": # 同步Agent状态 emit_signal("state_synced", message.get("state", {})) "heartbeat": # 响应心跳 send_command({"type": "heartbeat_ack", "timestamp": Time.get_unix_time_from_system()}) "error": print("Bridge error: ", message.get("error", "Unknown error")) _: print("Unknown message type: ", msg_type) func send_command(command: Dictionary) -> bool: if not is_connected or not socket: # 静默处理,不打印警告 return false var json_str = JSON.stringify(command) var err = socket.send_text(json_str) if err != OK: print("Failed to send command: ", err) return false return true func request_state_sync(): send_command({ "type": "request_state_sync", "agent_id": "val" }) func close_connection(): if socket: socket.close() is_connected = false