wanshenmean
2026-03-11 a8f45091019012eeafec563913dee71cda3d9790
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
@@ -1,17 +1,17 @@
using Quartz;
using Quartz;
using WIDESEA_Core;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core.Caches;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_Tasks.Workflow.Abstractions;
using WIDESEAWCS_Tasks.Workflow;
using WIDESEAWCS_Tasks.SocketServer;
namespace WIDESEAWCS_Tasks
{
    /// <summary>
    /// 机械手任务作业 - 负责协调机械手客户端连接、消息处理和任务执行
    /// 机器人任务作业:负责调度与生命周期管理,具体状态机流程交给编排器。
    /// </summary>
    [DisallowConcurrentExecution]
    public class RobotJob : IJob
@@ -22,9 +22,9 @@
        private readonly RobotClientManager _clientManager;
        private readonly RobotStateManager _stateManager;
        private readonly RobotMessageHandler _messageHandler;
        private readonly IRobotMessageRouter _messageRouter;
        private readonly RobotTaskProcessor _taskProcessor;
        private readonly IRobotTaskService _robotTaskService;
        private readonly IRobotWorkflowOrchestrator _workflowOrchestrator;
        public RobotJob(
            TcpSocketServer tcpSocket,
@@ -33,31 +33,32 @@
            ICacheService cache,
            HttpClientHelper httpClientHelper)
        {
            _robotTaskService = robotTaskService;
            // 初始化管理器
            _stateManager = new RobotStateManager(cache);
            _taskProcessor = new RobotTaskProcessor(tcpSocket, _stateManager, robotTaskService, taskService, httpClientHelper);
            _clientManager = new RobotClientManager(tcpSocket, _stateManager);
            _messageHandler = new RobotMessageHandler(tcpSocket, _stateManager, cache, robotTaskService, _taskProcessor);
            // 订阅客户端管理器的事件
            // 收口 Socket 访问,后续若替换通信实现只需替换网关层。
            ISocketClientGateway socketGateway = new SocketClientGateway(tcpSocket);
            _taskProcessor = new RobotTaskProcessor(socketGateway, _stateManager, robotTaskService, taskService, httpClientHelper);
            _clientManager = new RobotClientManager(tcpSocket, _stateManager);
            var simpleCommandHandler = new RobotSimpleCommandHandler(_taskProcessor);
            var prefixCommandHandler = new RobotPrefixCommandHandler(robotTaskService, _taskProcessor, _stateManager, socketGateway);
            _messageRouter = new RobotMessageHandler(socketGateway, _stateManager, cache, simpleCommandHandler, prefixCommandHandler);
            _workflowOrchestrator = new RobotWorkflowOrchestrator(_stateManager, _clientManager, _taskProcessor, robotTaskService);
            _clientManager.OnClientDisconnected += OnClientDisconnected;
            // 订阅TCP服务器的消息事件(全局只订阅一次)
            // 全局只订阅一次消息事件,保持原有行为。
            if (System.Threading.Interlocked.CompareExchange(ref _messageSubscribedFlag, 1, 0) == 0)
            {
                tcpSocket.MessageReceived += _messageHandler.HandleMessageReceivedAsync;
                Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 机器人TCP消息事件已订阅");
                tcpSocket.MessageReceived += _messageRouter.HandleMessageReceivedAsync;
                Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 机器手TCP消息事件已订阅");
            }
        }
        /// <summary>
        /// 客户端断开连接时的处理
        /// </summary>
        private void OnClientDisconnected(object? sender, RobotSocketState state)
        {
            // 可以在这里添加断开连接后的处理逻辑
            Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 客户端已断开连接: {state.IPAddress}");
        }
@@ -72,118 +73,34 @@
            string ipAddress = robotCrane.IPAddress;
            // 获取或创建状态
            RobotSocketState state = _stateManager.GetOrCreateState(ipAddress, robotCrane);
            state.RobotCrane = robotCrane;
            try
            {
                // 确保客户端已连接并订阅消息事件
                if (!_clientManager.EnsureClientSubscribed(ipAddress, robotCrane))
                {
                    return; // 客户端未连接或订阅失败,跳过本次执行
                    return;
                }
                // 获取任务并处理
                Dt_RobotTask? task = _taskProcessor.GetTask(robotCrane);
                var task = _taskProcessor.GetTask(robotCrane);
                if (task != null)
                {
                    // 每次判断前重新从缓存获取最新状态
                    var latestState = _stateManager.GetState(ipAddress);
                    if (latestState == null) return;
                    if (latestState == null)
                    {
                        return;
                    }
                    if (latestState.RobotTaskTotalNum < MaxTaskTotalNum)
                    {
                        await ProcessTaskAsync(latestState, task, ipAddress);
                        await _workflowOrchestrator.ExecuteAsync(latestState, task, ipAddress);
                    }
                }
            }
            catch (Exception)
            {
                // 异常处理已在各组件中处理
            }
        }
        /// <summary>
        /// 处理机械手任务
        /// </summary>
        private async Task ProcessTaskAsync(RobotSocketState latestState, Dt_RobotTask task, string ipAddress)
        {
            // 处理正在执行的任务
            if (latestState.RobotRunMode == 2 && latestState.RobotControlMode == 1 && latestState.OperStatus != "Running")
            {
                // 取货完成状态处理
                if ((latestState.CurrentAction == "PickFinished" || latestState.CurrentAction == "AllPickFinished") && latestState.RobotArmObject == 1 &&
                    task.RobotTaskState == TaskRobotStatusEnum.RobotPickFinish.GetHashCode())
                {
                    await HandlePickFinishedStateAsync(latestState, task, ipAddress);
                }
                // 放货完成状态处理
                else if ((latestState.CurrentAction == "PutFinished" || latestState.CurrentAction == "AllPutFinished") && latestState.OperStatus == "Homed" &&
                    latestState.RobotArmObject == 0 &&
                    (task.RobotTaskState == TaskRobotStatusEnum.RobotPutFinish.GetHashCode() ||
                    task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()))
                {
                    await HandlePutFinishedStateAsync(latestState, task, ipAddress);
                }
            }
        }
        /// <summary>
        /// 处理取货完成状态
        /// </summary>
        private async Task HandlePickFinishedStateAsync(RobotSocketState latestState, Dt_RobotTask task, string ipAddress)
        {
            string taskString = $"Putbattery,{task.RobotTargetAddress}";
            bool result = await _clientManager.SendToClientAsync(ipAddress, taskString);
            if (result)
            {
                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
                // 重新获取最新状态并更新
                var stateToUpdate = _stateManager.GetState(ipAddress);
                if (stateToUpdate != null)
                {
                    stateToUpdate.CurrentTask = task;
                    if (_stateManager.TryUpdateStateSafely(ipAddress, stateToUpdate))
                        await _robotTaskService.UpdateRobotTaskAsync(task);
                }
            }
        }
        /// <summary>
        /// 处理放货完成状态
        /// </summary>
        private async Task HandlePutFinishedStateAsync(RobotSocketState latestState, Dt_RobotTask task, string ipAddress)
        {
            // 重新获取最新状态
            var stateForUpdate = _stateManager.GetState(ipAddress);
            if (stateForUpdate == null) return;
            if (!stateForUpdate.IsSplitPallet && !stateForUpdate.IsGroupPallet)
            {
                stateForUpdate.IsSplitPallet = task.RobotTaskType == RobotTaskTypeEnum.SplitPallet.GetHashCode();
                stateForUpdate.IsGroupPallet = task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode() ||
                    task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode();
            }
            if (task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode())
            {
                string prefix = "TRAY";
                // 生成两个托盘条码
                string trayBarcode1 = RobotBarcodeGenerator.GenerateTrayBarcode(prefix);
                string trayBarcode2 = RobotBarcodeGenerator.GenerateTrayBarcode(prefix);
                if (!trayBarcode1.IsNullOrEmpty() && !trayBarcode2.IsNullOrEmpty())
                {
                    stateForUpdate.CellBarcode.Add(trayBarcode1);
                    stateForUpdate.CellBarcode.Add(trayBarcode2);
                    await _taskProcessor.SendSocketRobotPickAsync(task, stateForUpdate);
                }
            }
            else // 任务开始执行直接发送取货地址
            {
                await _taskProcessor.SendSocketRobotPickAsync(task, stateForUpdate);
                // 异常处理已在组件内部进行,Job 层保持兜底吞吐语义。
            }
        }
    }