#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 聊天 WebSocket 路由 处理前端与 OpenClaw Gateway 之间的消息转发 作者:小白 🐶 """ from flask import request, session from flask_login import current_user from flask_socketio import emit, join_room, leave_room import json import time from .openclaw_connector import gateway_manager # Gateway 配置(从环境变量或配置文件读取) GATEWAYS = { "local": { "url": "ws://127.0.0.1:18888", "token": "ae4d5989ba173a01cc721200614a8a8a8226724b46d5af13a65089aa628c32b9" } } def init_gateways(): """初始化 Gateway 连接""" for name, config in GATEWAYS.items(): connector = gateway_manager.add_gateway( name, config["url"], config["token"] ) # 设置消息回调 connector.message_callback = handle_gateway_response gateway_manager.connect_all() print(f"[Chat] Initialized {len(GATEWAYS)} gateway(s)") def handle_gateway_response(gateway_name: str, data: dict): """处理 Gateway 响应并转发给前端""" from app import socketio # 获取用户房间 user_id = data.get("params", {}).get("userId", "anonymous") room = f"user_{user_id}" # 转发给前端 socketio.emit('agent_response', { 'gateway': gateway_name, 'data': data, 'timestamp': int(time.time() * 1000) }, room=room, namespace='/chat') print(f"[Chat] Forwarded response to {room}") def register_socket_handlers(socketio): """注册 Socket.IO 事件处理器""" @socketio.on('connect', namespace='/chat') def handle_connect(): """用户连接""" if not current_user.is_authenticated: print("[Chat] Unauthorized connection attempt") return False user_id = current_user.id room = f"user_{user_id}" join_room(room) # 返回 Gateway 列表和状态 emit('connected', { 'gateways': gateway_manager.list_gateways(), 'status': gateway_manager.get_status(), 'userId': user_id }) print(f"[Chat] User {current_user.username} connected, room: {room}") @socketio.on('disconnect', namespace='/chat') def handle_disconnect(): """用户断开连接""" if current_user.is_authenticated: room = f"user_{current_user.id}" leave_room(room) print(f"[Chat] User {current_user.username} disconnected") @socketio.on('send_message', namespace='/chat') def handle_message(data): """处理用户消息""" if not current_user.is_authenticated: emit('error', {'message': '未授权'}) return gateway_name = data.get('gateway', 'local') message = data.get('message', '').strip() if not message: emit('error', {'message': '消息不能为空'}) return connector = gateway_manager.get_gateway(gateway_name) if connector and connector.connected: # 构造会话 key session_key = f"webchat:user_{current_user.id}" # 发送到 Gateway success = connector.send_message(message, session_key) if success: # 确认收到 emit('message_sent', { 'gateway': gateway_name, 'message': message, 'timestamp': int(time.time() * 1000) }) print(f"[Chat] User {current_user.username} sent message to {gateway_name}") else: emit('error', {'message': f'发送失败:Gateway {gateway_name} 连接异常'}) else: emit('error', {'message': f'Gateway {gateway_name} 未连接'}) @socketio.on('switch_gateway', namespace='/chat') def handle_switch(data): """切换 Gateway""" if not current_user.is_authenticated: return gateway_name = data.get('gateway') connector = gateway_manager.get_gateway(gateway_name) if connector: emit('gateway_changed', { 'gateway': gateway_name, 'connected': connector.connected, 'status': gateway_manager.get_status() }) print(f"[Chat] User {current_user.username} switched to {gateway_name}") else: emit('error', {'message': f'Gateway {gateway_name} 不存在'}) @socketio.on('get_status', namespace='/chat') def handle_get_status(): """获取 Gateway 状态""" emit('status_update', { 'status': gateway_manager.get_status() }) print("[Chat] Socket handlers registered")