feat(反向WS管理): 实现多前端支持与完善清理机制

- 为每个前端创建独立的Bot实例,防止状态混乱
- 分离消息锁和时间戳存储,修复清理逻辑错误
- 完善客户端断开时的清理逻辑,包括负载计数和健康状态
- 添加文档说明多前端支持的功能和解决方案
This commit is contained in:
2026-02-28 21:20:20 +08:00
parent b5e08833e0
commit 0baf07a716
2 changed files with 204 additions and 3 deletions

View File

@@ -20,6 +20,7 @@ from ..utils.error_codes import ErrorCode, create_error_response
from .command_manager import matcher
from models.events.factory import EventFactory
from .redis_manager import redis_manager
from ..bot import Bot
class ReverseWSManager:
@@ -48,11 +49,15 @@ class ReverseWSManager:
self._processed_events: Dict[str, datetime] = {} # 已处理的事件ID和时间
self._event_ttl = 60 # 事件ID保留时间
self._message_locks: Dict[str, asyncio.Lock] = {} # 消息处理锁
self._message_lock_times: Dict[str, datetime] = {} # 消息锁创建时间
self._lock_ttl = 300 # 锁保留时间(秒)
# 启动清理任务
self._cleanup_task = None
# Bot实例字典每个前端独立的Bot实例
self.bots: Dict[str, Bot] = {}
async def start(self, host: str = "0.0.0.0", port: int = 3002) -> None:
"""
启动反向 WebSocket 服务端。
@@ -162,11 +167,14 @@ class ReverseWSManager:
# 清理过期的消息锁
expired_locks = [
lock_key for lock_key, timestamp in self._message_locks.items()
lock_key for lock_key, timestamp in self._message_lock_times.items()
if (current_time - timestamp).total_seconds() > self._lock_ttl
]
for lock_key in expired_locks:
del self._message_locks[lock_key]
if lock_key in self._message_locks:
del self._message_locks[lock_key]
if lock_key in self._message_lock_times:
del self._message_lock_times[lock_key]
except asyncio.CancelledError:
break
@@ -184,6 +192,14 @@ class ReverseWSManager:
del self.clients[client_id]
if client_id in self.client_self_ids:
del self.client_self_ids[client_id]
if client_id in self._client_load:
del self._client_load[client_id]
if client_id in self._client_health:
del self._client_health[client_id]
if client_id in self.bots:
del self.bots[client_id]
self.logger.info(f"客户端已断开并清理: {client_id}")
async def _on_event(self, client_id: str, event_data: Dict[str, Any]) -> None:
"""
@@ -199,7 +215,16 @@ class ReverseWSManager:
if hasattr(event, 'self_id'):
self.client_self_ids[client_id] = event.self_id
event.bot = None
# 为事件注入Bot实例
from ..ws import WS
# 为每个前端创建独立的Bot实例
if client_id not in self.bots:
temp_ws = WS()
temp_ws.self_id = event.self_id if hasattr(event, 'self_id') else 0
self.bots[client_id] = Bot(temp_ws)
event.bot = self.bots[client_id]
# 记录客户端健康状态
self._client_health[client_id] = datetime.now()
@@ -392,6 +417,7 @@ class ReverseWSManager:
"""
if key not in self._message_locks:
self._message_locks[key] = asyncio.Lock()
self._message_lock_times[key] = datetime.now()
return self._message_locks[key]
def _update_client_load(self, client_id: str) -> None: