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");
}
}
}