Browse Source

修复 bug 问题

origin/hotfix/hlk-flight
root 4 months ago
parent
commit
3048a01027
  1. 95
      app/core/websocket/manager.py
  2. 36
      app/core/websocket/send_controller.py
  3. 1601
      modify.md

95
app/core/websocket/manager.py

@ -53,10 +53,24 @@ class WebSocketManager:
async def create_client(self, name: str, url: str, heartbeat_interval: int = 120) -> WebSocketClient:
"""创建WebSocket客户端并自动创建3个Channel"""
try:
# 1. 创建客户端
client = await self._client_manager.create_client(name, url, heartbeat_interval)
# 检查是否已存在客户端
existing_client = self._client_manager.get_client(name)
if existing_client:
logger.info(f"WebSocket客户端 {name} 已存在,检查状态")
# 如果客户端已连接,先断开
if existing_client.is_connected:
logger.info(f"WebSocket客户端 {name} 已连接,先断开")
await self._client_manager.disconnect_client(name)
# 更新心跳间隔配置
existing_client.heartbeat_interval = heartbeat_interval
client = existing_client
else:
# 1. 创建客户端
client = await self._client_manager.create_client(name, url, heartbeat_interval)
# 2. 创建Channel
# 2. 创建Channel(如果已存在会返回已存在的Channel)
await self._channel_manager.create_client_channels(name)
# 3. 注册消息处理器
@ -130,15 +144,20 @@ class WebSocketManager:
# 2. 启动Channel
await self._channel_manager.start_client_channels(name)
# 3. 创建并启动发送控制器
# 3. 等待Channel完全启动(确保Channel状态为connected)
await self._wait_for_channels_ready(name)
# 4. 创建并启动发送控制器
await self._create_and_start_send_controller(name)
# 4. 启动心跳任务
# 5. 启动心跳任务
client = self._client_manager.get_client(name)
if client and hasattr(client, 'heartbeat_interval'):
# 检查是否已存在心跳任务
await self._heartbeat_manager.stop_heartbeat_task(name) # 先停止已存在的任务
await self._heartbeat_manager.start_heartbeat_task(name, client, client.heartbeat_interval)
# 5. 启动接收消息处理器
# 6. 启动接收消息处理器
await self._create_and_start_receive_processor(name)
logger.info(f"WebSocket管理器客户端连接成功: {name}")
@ -148,6 +167,32 @@ class WebSocketManager:
logger.error(f"WebSocket管理器连接客户端失败: {name} - {e}")
return False
async def _wait_for_channels_ready(self, client_name: str, timeout: float = 5.0):
"""等待客户端的所有Channel完全启动"""
import asyncio
start_time = asyncio.get_event_loop().time()
while asyncio.get_event_loop().time() - start_time < timeout:
# 检查所有Channel是否都已连接
client_channels = self._channel_manager.get_client_channels(client_name)
all_connected = True
for channel_name, channel in client_channels.items():
if not channel.is_connected:
all_connected = False
logger.debug(f"等待Channel连接: {channel_name}")
break
if all_connected:
logger.info(f"所有Channel已准备就绪: {client_name}")
return True
# 等待100ms后再次检查
await asyncio.sleep(0.1)
logger.warning(f"等待Channel就绪超时: {client_name} (超时时间: {timeout}秒)")
return False
async def _create_and_start_send_controller(self, client_name: str):
"""创建并启动发送控制器"""
try:
@ -156,11 +201,26 @@ class WebSocketManager:
logger.error(f"WebSocket客户端 {client_name} 不存在")
return
# 检查是否已存在发送控制器
if client_name in self._send_controllers:
existing_controller = self._send_controllers[client_name]
logger.info(f"WebSocket发送控制器 {client_name} 已存在,先停止")
await existing_controller.stop()
del self._send_controllers[client_name]
# 获取Channel
heartbeat_channel = self._channel_manager.get_channel(f"{client_name}_heartbeat")
send_channel = self._channel_manager.get_channel(f"{client_name}_send")
if not heartbeat_channel or not send_channel:
logger.error(f"Channel不存在,无法创建发送控制器: {client_name}")
return
# 创建发送控制器
send_controller = WebSocketSendController(
client=client,
heartbeat_channel_name=f"{client_name}_heartbeat",
send_channel_name=f"{client_name}_send"
heartbeat_channel=heartbeat_channel,
send_channel=send_channel
)
# 启动发送控制器
@ -177,6 +237,18 @@ class WebSocketManager:
async def _create_and_start_receive_processor(self, client_name: str):
"""创建并启动接收消息处理器"""
try:
# 检查是否已存在接收处理器
if client_name in self._receive_tasks:
existing_task = self._receive_tasks[client_name]
logger.info(f"WebSocket接收消息处理器 {client_name} 已存在,先停止")
if not existing_task.done():
existing_task.cancel()
try:
await existing_task
except asyncio.CancelledError:
pass
del self._receive_tasks[client_name]
# 获取接收Channel
receive_channel = self._channel_manager.get_channel(f"{client_name}_receive")
if not receive_channel:
@ -286,10 +358,13 @@ class WebSocketManager:
# 3. 停止接收消息处理器
await self._stop_receive_processor(name)
# 4. 停止Channel
# 4. 等待发送控制器完全停止(确保不再访问Channel)
await asyncio.sleep(0.1)
# 5. 停止Channel
await self._channel_manager.stop_client_channels(name)
# 5. 断开客户端
# 6. 断开客户端
success = await self._client_manager.disconnect_client(name)
logger.info(f"WebSocket管理器客户端断开成功: {name}")

36
app/core/websocket/send_controller.py

@ -6,7 +6,7 @@ WebSocket发送控制器
import asyncio
from typing import Dict, Any, Optional
from datetime import datetime
from app.core.websocket.channel import ChannelMessage
from app.core.websocket.channel import ChannelMessage, WebSocketChannel
from app.core.websocket.client import WebSocketClient
from app.utils.structured_log import get_structured_logger, LogLevel
@ -23,11 +23,11 @@ class WebSocketSendController:
- 发送任务管理
"""
def __init__(self, client: WebSocketClient, heartbeat_channel_name: str, send_channel_name: str):
def __init__(self, client: WebSocketClient, heartbeat_channel: WebSocketChannel, send_channel: WebSocketChannel):
self.client = client
self.client_name = client.name
self.heartbeat_channel_name = heartbeat_channel_name
self.send_channel_name = send_channel_name
self.heartbeat_channel = heartbeat_channel
self.send_channel = send_channel
self._send_task: Optional[asyncio.Task] = None
self._running = False
self._created_at = datetime.now()
@ -84,26 +84,24 @@ class WebSocketSendController:
try:
while self._running and self.client.is_connected:
try:
# 获取Channel管理器
from app.core.websocket.channel_manager import WebSocketChannelManager
channel_manager = WebSocketChannelManager()
# 获取Channel
heartbeat_channel = channel_manager.get_channel(self.heartbeat_channel_name)
send_channel = channel_manager.get_channel(self.send_channel_name)
if not heartbeat_channel or not send_channel:
# 检查Channel是否存在且已连接
if not self.heartbeat_channel or not self.send_channel:
logger.warning(f"Channel不存在,等待重试: {self.client_name}")
await asyncio.sleep(1)
continue
if not self.heartbeat_channel.is_connected or not self.send_channel.is_connected:
logger.warning(f"Channel未连接,等待重试: {self.client_name}")
await asyncio.sleep(1)
continue
# 优先级发送:先发送业务数据,再发送心跳
message_sent = False
# 1. 优先发送业务数据
if send_channel.is_connected and send_channel.queue_size > 0:
if self.send_channel.queue_size > 0:
try:
message = await send_channel.receive_message()
message = await self.send_channel.receive_message()
if message:
success = await self._send_message(message)
if success:
@ -115,9 +113,9 @@ class WebSocketSendController:
logger.error(f"WebSocket发送控制器发送业务消息异常: {self.client_name} - {e}")
# 2. 如果没有业务数据,发送心跳
if not message_sent and heartbeat_channel.is_connected and heartbeat_channel.queue_size > 0:
if not message_sent and self.heartbeat_channel.queue_size > 0:
try:
message = await heartbeat_channel.receive_message()
message = await self.heartbeat_channel.receive_message()
if message:
success = await self._send_message(message)
if success:
@ -189,6 +187,6 @@ class WebSocketSendController:
"is_running": self._running,
"is_connected": self.client.is_connected,
"created_at": self._created_at.isoformat(),
"heartbeat_channel": self.heartbeat_channel_name,
"send_channel": self.send_channel_name
"heartbeat_channel": self.heartbeat_channel.name,
"send_channel": self.send_channel.name
}

1601
modify.md

File diff suppressed because it is too large
Loading…
Cancel
Save