using System.Net.Sockets; using WIDESEAWCS_Common; using WIDESEAWCS_Common.HttpEnum; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core.Caches; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_DTO.Stock; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_Tasks.SocketServer; namespace WIDESEAWCS_Tasks { /// /// 机械手消息处理器 - 负责处理来自TCP客户端的消息 /// public class RobotMessageHandler { private readonly TcpSocketServer _tcpSocket; private readonly RobotStateManager _stateManager; private readonly ICacheService _cache; private readonly IRobotTaskService _robotTaskService; private readonly RobotTaskProcessor _taskProcessor; public RobotMessageHandler( TcpSocketServer tcpSocket, RobotStateManager stateManager, ICacheService cache, IRobotTaskService robotTaskService, RobotTaskProcessor taskProcessor) { _tcpSocket = tcpSocket; _stateManager = stateManager; _cache = cache; _robotTaskService = robotTaskService; _taskProcessor = taskProcessor; } /// /// 处理接收到的消息 /// public async Task HandleMessageReceivedAsync(string message, bool isJson, TcpClient client, RobotSocketState state) { if (!(_cache?.TryGetValue($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{client.Client.RemoteEndPoint}", out state)) ?? false) return null; string messageLower = message.ToLowerInvariant(); if (await IsSimpleCommandAsync(messageLower, state)) { await _tcpSocket.SendMessageAsync(client, message); if (_stateManager.TryUpdateStateSafely(state.IPAddress, state)) return null; } else if (IsPrefixCommand(messageLower)) { await HandlePrefixCommandAsync(message, state, client); } return null; } /// /// 处理前缀命令(pickfinished, putfinished) /// private async Task HandlePrefixCommandAsync(string message, RobotSocketState state, TcpClient client) { try { var parts = message.Split(','); if (parts.Length >= 1 && state.CurrentTask != null) { var cmd = parts[0].ToLowerInvariant(); int[] positions = parts.Skip(1) .Select(p => int.TryParse(p, out int value) ? value : (int?)null) .Where(v => v.HasValue && v.Value != 0) .Select(v => v!.Value) .ToArray(); var task = await _robotTaskService.Repository.QueryFirstAsync(x => x.RobotTaskId == state.CurrentTask.RobotTaskId); if (cmd.StartsWith("pickfinished")) { await HandlePickFinishedAsync(state, positions, task, client); } else if (cmd.StartsWith("putfinished")) { await HandlePutFinishedAsync(state, positions, task, client); } await _tcpSocket.SendMessageAsync(client, message); } } catch (Exception ex) { Console.WriteLine($"RobotJob MessageReceived Error: {ex.Message}"); } } /// /// 处理取货完成命令 /// private async Task HandlePickFinishedAsync(RobotSocketState state, int[] positions, Dt_RobotTask? task, TcpClient client) { if (state.IsSplitPallet) { var stockDTO = RobotTaskProcessor.BuildStockDTO(state, positions); state.LastPickPositions = positions; var result = _taskProcessor.PostSplitPalletAsync(stockDTO); if (result.Data.Status && result.IsSuccess) { state.CurrentAction = "PickFinished"; } } else { state.CurrentAction = "PickFinished"; } state.LastPickPositions = positions; if (task != null) { task.RobotTaskState = TaskRobotStatusEnum.RobotPickFinish.GetHashCode(); if (_stateManager.TryUpdateStateSafely(state.IPAddress, state)) await _robotTaskService.Repository.UpdateDataAsync(task); } } /// /// 处理放货完成命令 /// private async Task HandlePutFinishedAsync(RobotSocketState state, int[] positions, Dt_RobotTask? task, TcpClient client) { bool putSuccess = true; if (state.IsGroupPallet) { state.LastPutPositions = positions; var stockDTO = RobotTaskProcessor.BuildStockDTO(state, positions); var configKey = state.CurrentTask?.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode() ? nameof(ConfigKey.ChangePalletAsync) : nameof(ConfigKey.GroupPalletAsync); var result = _taskProcessor.PostGroupPalletAsync(configKey, stockDTO); putSuccess = result.Data.Status && result.IsSuccess; } if (putSuccess) { state.CurrentAction = "PutFinished"; state.RobotTaskTotalNum += positions.Length; if (task != null) { task.RobotTaskTotalNum += positions.Length; } } if (task != null) { task.RobotTaskState = TaskRobotStatusEnum.RobotPutFinish.GetHashCode(); if (_stateManager.TryUpdateStateSafely(state.IPAddress, state)) await _robotTaskService.Repository.UpdateDataAsync(task); } } /// /// 机械手简单命令处理 /// private async Task IsSimpleCommandAsync(string message, RobotSocketState state) { RobotTaskTypeEnum? GetRobotTaskType() => state.CurrentTask != null ? (RobotTaskTypeEnum)state.CurrentTask.RobotTaskType : null; switch (message) { case "homing": state.OperStatus = "Homing"; return true; case "homed": state.OperStatus = "Homed"; return true; case "picking": state.CurrentAction = "Picking"; return true; case "puting": state.CurrentAction = "Putting"; return true; case "allpickfinished": // 取货完成 state.CurrentAction = "AllPickFinished"; var robotTaskType = GetRobotTaskType(); if (robotTaskType == RobotTaskTypeEnum.SplitPallet || robotTaskType == RobotTaskTypeEnum.ChangePallet) { if (await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true)) { _taskProcessor.DeleteTask(state.CurrentTask.RobotTaskId); return true; } } return false; case "allputfinished": // 放货完成 state.CurrentAction = "AllPutFinished"; robotTaskType = GetRobotTaskType(); if (robotTaskType == RobotTaskTypeEnum.GroupPallet || robotTaskType == RobotTaskTypeEnum.ChangePallet) { if (await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: false)) { _taskProcessor.DeleteTask(state.CurrentTask.RobotTaskId); state.CurrentTask = null; state.RobotTaskTotalNum = 0; state.CellBarcode = new List(); return true; } } return false; case "running": state.OperStatus = "Running"; return true; case "pausing": state.OperStatus = "Pausing"; return true; case "warming": state.OperStatus = "Warming"; return true; case "emstoping": state.OperStatus = "Emstoping"; return true; case "runmode,1": state.RobotRunMode = 1; return true; case "runmode,2": state.RobotRunMode = 2; return true; case "controlmode,1": state.RobotControlMode = 1; return true; case "controlmode,2": state.RobotControlMode = 2; return true; case "armobject,1": state.RobotArmObject = 1; return true; case "armobject,0": state.RobotArmObject = 0; return true; default: return false; } } /// /// 判断是否为前缀命令 /// private static bool IsPrefixCommand(string message) { return message.StartsWith("pickfinished") || message.StartsWith("putfinished"); } } }