using Quartz; using System.Collections.Concurrent; using System.Net.Sockets; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_Tasks.SocketServer; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public class RobotJob : IJob { private readonly TcpSocketServer _TcpSocket; private static readonly ConcurrentDictionary _socketStates = new(); private static int _eventSubscribedFlag; private readonly ITaskService _taskService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly ITaskRepository _taskRepository; private readonly IRouterService _routerService; public RobotJob(TcpSocketServer TcpSocket, ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService) { _TcpSocket = TcpSocket; _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _taskRepository = taskRepository; _routerService = routerService; } public Task Execute(IJobExecutionContext context) { bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value); RobotCraneDevice robotCrane = (RobotCraneDevice?)value ?? new RobotCraneDevice(); if (!flag || robotCrane.IsNullOrEmpty()) { return Task.CompletedTask; } string ipAddress = robotCrane.IPAddress; // 获取或创建状态 RobotSocketState state = _socketStates.GetOrAdd(ipAddress, _ => new RobotSocketState { IPAddress = ipAddress, RobotCrane = robotCrane }); // 更新设备信息 state.RobotCrane = robotCrane; // 检查是否有该客户端连接 var clientIds = _TcpSocket.GetClientIds(); if (!clientIds.Contains(ipAddress)) { return Task.CompletedTask; } // 订阅一次 message 事件(全局一次) if (Interlocked.CompareExchange(ref _eventSubscribedFlag, 1, 0) == 0) { _TcpSocket.MessageReceived += _TcpSocket_MessageReceived; _TcpSocket.RobotReceived += _TcpSocket_RobotReceived; } if (!state.IsEventSubscribed) { _TcpSocket._clients.TryGetValue(ipAddress, out TcpClient client); Task clientTask = _TcpSocket.HandleClientAsync(client, robotCrane.IPAddress, _TcpSocket._cts.Token, state); state.IsEventSubscribed = true; } // 获取任务并缓存到状态中 Dt_Task? task = GetTask(robotCrane); if (task != null) { state.CurrentTask = task; } return Task.CompletedTask; } /// /// 事件:客户端断开连接时触发 /// /// /// private Task _TcpSocket_RobotReceived(string clientId) { _socketStates.TryRemove(clientId, out _); return Task.FromResult(null); } /// /// 事件:收到消息时触发 /// /// /// /// /// /// private async Task _TcpSocket_MessageReceived(string message, bool isJson, TcpClient client, RobotSocketState state) { string messageLower = message.ToLowerInvariant(); if (IsSimpleCommand(messageLower, state)) { return null; } if (IsPrefixCommand(messageLower)) { try { var parts = message.Split(','); if (parts.Length >= 1) { var cmd = parts[0].ToLowerInvariant(); int[] positions = new int[4]; for (int i = 1; i <= 4 && i < parts.Length; i++) { int.TryParse(parts[i], out positions[i - 1]); } if (cmd.StartsWith("pickfinished")) { state.LastPickPositions = positions; state.CurrentAction = "PickFinished"; } else if (cmd.StartsWith("putfinished")) { state.LastPutPositions = positions; state.CurrentAction = "PutFinished"; } } } catch { } return null; } return null; } /// /// 机械手简单命令处理 /// /// /// /// private bool IsSimpleCommand(string message, RobotSocketState state) { switch (message) { case "homing": state.CurrentAction = "Homing"; return true; case "homed": state.CurrentAction = "Homed"; return true; case "picking": state.CurrentAction = "Picking"; return true; case "puting": state.CurrentAction = "Putting"; return true; case "allpickfinished": state.CurrentAction = "AllPickFinished"; return true; case "allputfinished": state.CurrentAction = "AllPutFinished"; return true; 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 "runmodemode,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"); } private Dt_Task? GetTask(RobotCraneDevice robotCrane) { return _taskService.QueryRobotCraneTask(robotCrane.DeviceCode); } } public class RobotSocketState { public string IPAddress { get; set; } = string.Empty; /// /// 是否已订阅消息事件 /// public bool IsEventSubscribed { get; set; } /// /// 机械手运行模式 /// public int? RobotRunMode { get; set; } /// /// 机械手控制模式 /// public int? RobotControlMode { get; set; } /// /// 机械手抓取对象 /// public int? RobotArmObject { get; set; } /// /// 机械手设备信息 /// public RobotCraneDevice? RobotCrane { get; set; } /// /// 当前动作 /// public string? CurrentAction { get; set; } /// /// 当前状态 /// public string? OperStatus { get; set; } /// /// 取货完成位置 /// public int[]? LastPickPositions { get; set; } /// /// 放货完成位置 /// public int[]? LastPutPositions { get; set; } /// /// 当前抓取任务 /// public Dt_Task? CurrentTask { get; set; } } }