feat(反向WS管理): 实现多前端支持与完善清理机制
- 为每个前端创建独立的Bot实例,防止状态混乱 - 分离消息锁和时间戳存储,修复清理逻辑错误 - 完善客户端断开时的清理逻辑,包括负载计数和健康状态 - 添加文档说明多前端支持的功能和解决方案
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user