import json
|
|
from dataclasses import dataclass
|
|
from typing import Dict, List, Optional, Union
|
|
|
|
from fastapi import APIRouter, WebSocket, WebSocketDisconnect
|
|
from pynput.keyboard import Controller as KeyboardController
|
|
from pynput.keyboard import Key
|
|
from pynput.mouse import Button, Controller
|
|
|
|
router = APIRouter()
|
|
|
|
# 存储活跃的WebSocket连接
|
|
active_connection: Optional[WebSocket] = None
|
|
|
|
|
|
@dataclass
|
|
class WebSocketMessage:
|
|
"""WebSocket消息数据类"""
|
|
|
|
type: str
|
|
msg: str = ""
|
|
title: str = "提示"
|
|
duration: int = 1
|
|
data: Dict = None
|
|
|
|
def __post_init__(self):
|
|
if self.data is None:
|
|
self.data = {"x": 0, "y": 0, "key_str": ""}
|
|
|
|
def to_dict(self) -> Dict:
|
|
"""将消息转换为字典格式"""
|
|
return {
|
|
"type": self.type,
|
|
"msg": self.msg,
|
|
"title": self.title,
|
|
"duration": self.duration,
|
|
"data": self.data,
|
|
}
|
|
|
|
|
|
class WebSocketMessageType:
|
|
"""WebSocket消息类型常量"""
|
|
|
|
# 系统消息类型
|
|
INFO = "info"
|
|
SUCCESS = "success"
|
|
WARNING = "warning"
|
|
ERROR = "error"
|
|
|
|
# 鼠标操作类型
|
|
MOUSE_MOVE = "mouse_move"
|
|
MOUSE_CLICK = "mouse_click"
|
|
|
|
|
|
class MessageSender:
|
|
"""消息发送器,发送给前端"""
|
|
|
|
@staticmethod
|
|
async def send_message(
|
|
ws_data_type: str, msg: str, title: str = "提示", duration: int = 1
|
|
) -> None:
|
|
"""
|
|
发送消息到WebSocket客户端
|
|
|
|
Args:
|
|
ws_data_type: 消息类型
|
|
msg: 消息内容
|
|
title: 消息标题
|
|
duration: 显示持续时间
|
|
"""
|
|
if not active_connection:
|
|
return
|
|
|
|
try:
|
|
message = WebSocketMessage(
|
|
type=ws_data_type, msg=msg, title=title, duration=duration
|
|
)
|
|
await active_connection.send_json(message.to_dict())
|
|
except Exception as e:
|
|
print(f"发送消息失败: {e}")
|
|
|
|
|
|
class GestureHandler:
|
|
"""手势控制器"""
|
|
|
|
def __init__(self):
|
|
self.keyboard = KeyboardController()
|
|
self.mouse = Controller()
|
|
|
|
def move_mouse(self, x: int, y: int) -> None:
|
|
"""移动鼠标到指定位置"""
|
|
print(f"👉 正在移动鼠标到位置: ({x}, {y})")
|
|
self.mouse.position = (x, y)
|
|
|
|
def click_mouse(self) -> None:
|
|
"""点击鼠标左键"""
|
|
print("👉 正在点击鼠标")
|
|
self.mouse.click(Button.left)
|
|
|
|
|
|
|
|
@router.websocket("/ws_wavecontrol")
|
|
async def websocket_endpoint(websocket: WebSocket):
|
|
"""WebSocket端点处理函数"""
|
|
global active_connection
|
|
|
|
await websocket.accept()
|
|
active_connection = websocket
|
|
|
|
gesture_handler = GestureHandler()
|
|
try:
|
|
while True:
|
|
data_str = await websocket.receive_text()
|
|
await _handle_message(data_str, websocket, gesture_handler)
|
|
except WebSocketDisconnect:
|
|
active_connection = None
|
|
except Exception as e:
|
|
print(f"WebSocket处理错误: {e}")
|
|
active_connection = None
|
|
|
|
|
|
async def _handle_message(
|
|
data_str: str,
|
|
websocket: WebSocket,
|
|
gesture_handler: GestureHandler,
|
|
) -> None:
|
|
"""处理WebSocket消息"""
|
|
try:
|
|
message = WebSocketMessage(**json.loads(data_str))
|
|
data = message.data
|
|
print(f"[收到指令] type={message.type}, data={data}") # 调试输出
|
|
|
|
|
|
# 处理鼠标操作
|
|
if message.type == WebSocketMessageType.MOUSE_MOVE:
|
|
gesture_handler.move_mouse(data["x"], data["y"])
|
|
elif message.type == WebSocketMessageType.MOUSE_CLICK:
|
|
gesture_handler.click_mouse()
|
|
|
|
except json.JSONDecodeError:
|
|
print("无效的JSON数据")
|
|
except Exception as e:
|
|
print(f"处理消息失败: {e}")
|