using Microsoft.Extensions.Logging; using System.Net.Sockets; using WIDESEAWCS_Common; using WIDESEAWCS_Core.LogHelper; using WIDESEAWCS_Model.Models; using WIDESEAWCS_Tasks.Workflow.Abstractions; namespace WIDESEAWCS_Tasks { /// /// 机器人消息处理器 - 消息路由入口 /// /// /// 核心职责: /// 1. 状态接收:从调用方获取机器人最新的状态 /// 2. 命令分发:根据消息类型分发给不同的处理器 /// - 简单命令(如 homing、running):由 处理 /// - 前缀命令(如 pickfinished、putfinished):由 处理 /// 3. 回包触发:将原始消息回写到客户端 /// /// 这是消息处理管道的入口点,由 TcpSocketServer 的 MessageReceived 事件触发。 /// public class RobotMessageHandler : IRobotMessageRouter { /// /// Socket 客户端网关接口 /// private readonly ISocketClientGateway _socketClientGateway; /// /// 机械手状态管理器 /// private readonly RobotStateManager _stateManager; /// /// 简单命令处理器 /// private readonly IRobotSimpleCommandHandler _simpleCommandHandler; /// /// 前缀命令处理器 /// private readonly IRobotPrefixCommandHandler _prefixCommandHandler; /// /// 日志记录器 /// private readonly ILogger _logger; /// /// 构造函数 /// /// Socket 网关 /// 状态管理器 /// 简单命令处理器 /// 前缀命令处理器 /// 日志记录器 public RobotMessageHandler( ISocketClientGateway socketClientGateway, RobotStateManager stateManager, IRobotSimpleCommandHandler simpleCommandHandler, IRobotPrefixCommandHandler prefixCommandHandler, ILogger logger) { _socketClientGateway = socketClientGateway; _stateManager = stateManager; _simpleCommandHandler = simpleCommandHandler; _prefixCommandHandler = prefixCommandHandler; _logger = logger; } /// /// 处理接收到的消息 /// /// /// 处理流程: /// 1. 记录日志(记录原始消息内容) /// 2. 尝试用简单命令处理器处理(状态更新类命令) /// - 如果处理成功,回写原消息并更新状态 /// 3. 如果不是简单命令,检查是否是前缀命令(pickfinished/putfinished) /// - 如果是,调用前缀命令处理器处理 /// 4. 保持原有行为:简单命令和前缀命令都回写原消息 /// /// 注意:此方法可能在 TCP 消息接收的上下文中被频繁调用,需注意性能。 /// /// 原始消息字符串 /// 消息是否为 JSON 格式(当前未使用) /// TCP 客户端连接 /// 机器人当前状态 /// 响应消息,如果无需回复则返回 null public async Task HandleMessageReceivedAsync(string message, bool isJson, TcpClient client, RobotSocketState state) { // 记录接收到的消息日志 _logger.LogInformation($"接收到客户端【{state.RobotCrane?.DeviceName}】发送消息【{message}】"); QuartzLogger.Info($"接收到客户端消息【{message}】", state.RobotCrane?.DeviceName); // 检查任务总数是否未达到上限 if (state.RobotTaskTotalNum > RobotConst.MaxTaskTotalNum) { _logger.LogInformation($"接收到客户端【{state.RobotCrane?.DeviceName}】发送消息【{message}】"); QuartzLogger.Info($"接收到客户端消息【{message}】", state.RobotCrane?.DeviceName); await _socketClientGateway.SendMessageAsync(client, message); return null; } // 将消息转换为小写(用于简单命令匹配) string messageLower = message.ToLowerInvariant(); // 尝试用简单命令处理器处理 // 简单命令包括:homing、homed、running、pausing、runmode、controlmode 等 if (await _simpleCommandHandler.HandleAsync(messageLower, state)) { // 处理成功后,将原消息回写到客户端(保持原有行为) await _socketClientGateway.SendMessageAsync(client, message); QuartzLogger.Info($"发送消息:【{message}】", state.RobotCrane?.DeviceName); // 安全更新状态到数据库 _stateManager.TryUpdateStateSafely(state.IPAddress, state); return null; } // 如果不是简单命令,检查是否是前缀命令 // 前缀命令包括:pickfinished、putfinished(后面跟逗号分隔的位置参数) if (_prefixCommandHandler.IsPrefixCommand(messageLower)) { // 调用前缀命令处理器 await _prefixCommandHandler.HandleAsync(message, state, client); } return null; } } }