using Newtonsoft.Json.Linq; using Sodao.FastSocket.Server.Messaging; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using BiosenSocketService.Exceptions; using XImaging.Automation.Library.HxDriverLib; using XImaging.Automation.Service; using XImaging.Automation.Service.Instruction; using Sodao.FastSocket.SocketBase.Utils; using System.Xml.Linq; namespace XImaging.Automation.Service.Instruction { public delegate void TroubleShootDelegate(); public delegate void OnTaskFinishDelegate(TaskInstruction tIns, JObject data, int status); public delegate void OnTaskAbortDelegate(TaskInstruction tIns, string errCode, string errString); public delegate void QueryDataDelegate(JObject data); /* * HxTroubleShoot * 记录并处理任务指令中途错误的类 */ public class HxTroubleShoot { public const int TS_Ignore = 1; // 错误处理方式:忽略 public const int TS_Retry = 2; // 错误处理方式:重试 public const int TS_Abort = 4; // 错误处理方式:中断 private string str_errCode; // 错误码 private int p_Troubleshoot=7; // 可能的错误处理方式,0-7 private string str_Message; // 错误信息 private int nDealwithtype = 0; public event TroubleShootDelegate IgnoreTrigger; // Ignore事件 public event TroubleShootDelegate RetryTrigger; // Retry事件 public event TroubleShootDelegate AbortTrigger; // Abort事件 private bool b_onWaiting = false; private int r_Troubleshoot = -1; // 用户反馈的错误处理方式 /// /// 记录新错误的信息 /// /// 错误码 /// 可行的处理方式 /// 错误信息 public void Error(HxMessage hxMessage, string errCode, int TroubleshootPossibility, string MsgText, int nDealwithtype) { //while (b_onWaiting) //{ // Thread.Sleep(1000); //} this.str_errCode = errCode; this.p_Troubleshoot = TroubleshootPossibility; this.str_Message = MsgText; this.nDealwithtype = nDealwithtype; JObject err = JObject.FromObject( new { error_code = str_errCode, error_text = str_Message, troubleshoot = p_Troubleshoot, dealwithtype= nDealwithtype, } ); HxTcpHandler.ReplyErrorMessage(hxMessage, err , str_errCode, str_Message, nDealwithtype, p_Troubleshoot); } /// /// 记录新错误的信息 /// /// 错误码 /// 可行的处理方式 /// 错误信息 public void Abort(HxMessage hxMessage, string errCode, int TroubleshootPossibility, string MsgText, int nDealwithtype) { while (b_onWaiting) { Thread.Sleep(1000); } this.str_errCode = errCode; this.p_Troubleshoot = TroubleshootPossibility; this.str_Message = MsgText; this.nDealwithtype = nDealwithtype; HxTcpHandler.ReplyFailedMessage(hxMessage, hxMessage.OriginJSON, str_errCode, str_Message, nDealwithtype, p_Troubleshoot, nDealwithtype); } public bool MatchTSCode(int TS_Code) { return (p_Troubleshoot & TS_Code) > 0; } /// /// 阻塞等待用户反馈 /// public void Wait() { b_onWaiting = true; while (r_Troubleshoot < 0) { Thread.Sleep(500); } b_onWaiting = false; } /// /// 异步等待用户反馈 /// public async void WaitAsync() { b_onWaiting = true; await Task.Run(() => { while (r_Troubleshoot < 0) { Thread.Sleep(500); } }); b_onWaiting = false; } /// /// 同步处理用户反馈 /// /// public void Reply(int TroubleshootReply) { r_Troubleshoot = TroubleshootReply; if (TroubleshootReply == TS_Ignore) IgnoreTrigger.Invoke(); else if (TroubleshootReply == TS_Retry) RetryTrigger.Invoke(); else if (TroubleshootReply == TS_Abort) AbortTrigger.Invoke(); } /// /// 异步处理用户反馈 /// /// public async void ReplyAsync(int TroubleshootReply) { r_Troubleshoot = TroubleshootReply; if (TroubleshootReply == TS_Ignore) await Task.Run(() => { IgnoreTrigger.Invoke(); }); else if (TroubleshootReply == TS_Retry) await Task.Run(() => { RetryTrigger.Invoke(); }); else if (TroubleshootReply == TS_Abort) await Task.Run(() => { AbortTrigger.Invoke(); }); } ~HxTroubleShoot() { Delegate[] dels; if (IgnoreTrigger != null) { dels = IgnoreTrigger.GetInvocationList(); foreach (Delegate del in dels) { object delObj = del.GetType().GetProperty("Method").GetValue(del, null); string funcName = (string)delObj.GetType().GetProperty("Name").GetValue(delObj, null); Console.WriteLine(funcName); IgnoreTrigger -= del as TroubleShootDelegate; } } if (RetryTrigger != null) { dels = RetryTrigger.GetInvocationList(); foreach (Delegate del in dels) { object delObj = del.GetType().GetProperty("Method").GetValue(del, null); string funcName = (string)delObj.GetType().GetProperty("Name").GetValue(delObj, null); Console.WriteLine(funcName); RetryTrigger -= del as TroubleShootDelegate; } } if (AbortTrigger != null) { dels = AbortTrigger.GetInvocationList(); foreach (Delegate del in dels) { object delObj = del.GetType().GetProperty("Method").GetValue(del, null); string funcName = (string)delObj.GetType().GetProperty("Name").GetValue(delObj, null); Console.WriteLine(funcName); AbortTrigger -= del as TroubleShootDelegate; } } } } interface IInstruction { } public class HxInstruction: IInstruction { public const int INSTYPE_HeartBeat = 0; // 类型:心跳包 public const int INSTYPE_Task = 1; // 类型:任务,指有较长执行时间的指令 public const int INSTYPE_Query = 2; // 类型:查询,指即时返回的指令 public const int INSTYPE_Troubleshoot = 3; // 类型:错误处理,指客户端返回的问题处理指令 public const int TASKSTAT_Scheduled = 0; // 状态:准备执行 public const int TASKSTAT_InProgress = 1; // 状态:正在执行 public const int TASKSTAT_Completed = 2; // 状态:执行完成 public const int TASKSTAT_Failed = 3; // 状态:执行失败 public const int TASKSTAT_Canceled = 4; // 状态:任务取消 protected HxMessage m_Message; // 接收到的Socket信息包 protected int n_TaskStatus; // 任务状态 public HxInstruction(HxMessage message) { m_Message = message; n_TaskStatus = -1; // HxInstruction.TASKSTAT_Scheduled; } public string InsId { get { return m_Message.MessageID; } } // 指令ID,唯一 public string InsName { get { return m_Message.Method; } } // 指令名 public int Type { get { return m_Message.MessageType; } } // 指令类型 public int Status { get { return n_TaskStatus; } } // 指令执行状态 public HxMessage Message { get { return m_Message; } } } /* * 心跳包指令 */ public class HeartBeatInstruction : HxInstruction { public HeartBeatInstruction(HxMessage message) : base(message) { } } /* * 任务指令 */ public class TaskInstruction : HxInstruction { HxInsParser command = null; public HxTroubleShoot ErrorHandler; public TaskInstruction(HxMessage message) : base(message) { ErrorHandler = new HxTroubleShoot(); } public TaskInstruction(HxMessage message, HxInsParser cmd) : base(message) { ErrorHandler = new HxTroubleShoot(); command = cmd; } public void OnTaskError(Object objMsg, string errCode, int TroubleshootPossibility, string message, int dealwithtype) { LogConstant.logger.Print($"OnTaskError: {message}"); JObject jObj = objMsg as JObject; string id = jObj["message_id"].ToString(); if (Message.MessageID == id) ErrorHandler.Error(this.Message, errCode, TroubleshootPossibility, message, dealwithtype); //ErrorHandler.WaitAsync(); } public void OnTaskAbort(Object objMsg, string errCode, int TroubleshootPossibility, string message, int dealwithtype) { ErrorHandler.Abort(this.Message, errCode, TroubleshootPossibility, message, dealwithtype); //ErrorHandler.WaitAsync(); } public void OnFinishTest(Dictionary result) { JObject data = new JObject();// StartExperimentInsArgs.ReturnDataWrapper(result); HxTcpHandler.ReplyFinishMessage(this.Message, data); } // 指令已收到,执行状态转为Scheduled public void Standby() { n_TaskStatus = TASKSTAT_Scheduled; } // 指令下发设备,开始正式执行 public void Execute() { n_TaskStatus = TASKSTAT_InProgress; } // 指令已经执行完毕,并正常结束 public void Finish() { n_TaskStatus = TASKSTAT_Completed; } // 指令已经执行但被迫中断或执行失败 public void Abort() { n_TaskStatus = TASKSTAT_Failed; } } /* * 查询指令 */ public class QueryInstruction : HxInstruction { HxInsParser command = null; public QueryDataDelegate OnDataReturned; public QueryInstruction(HxMessage message) : base(message){} public QueryInstruction(HxMessage message, HxInsParser cmd) : base(message) { command = cmd; } } /* * 错误处理指令 */ public class TroubleshootInstruction : HxInstruction { public TroubleshootInstruction(HxMessage message) : base(message) { } public int TSCode { get { return m_Message.Troubleshoot; } } } public class InstructionManager { TaskInstruction t_Instrction = null; // 任务指令 //ConcurrentQueue q_Instructions; // 查询指令队列 readonly static object qryLock = new object(); // 查询指令队列锁 System.Threading.Timer qTimer; private InsProtocol insProtocol; /// /// 监控查询指令队列 /// /// 占位参数 /*protected void QueueObserver(object state) { QueryInstruction qIns = null; bool deqFlag = false; lock (qryLock) { // 当查询队列中有指令未处理时取出 if (q_Instructions.Count > 0) deqFlag = q_Instructions.TryDequeue(out qIns); else return; } try { if (deqFlag && qIns != null) { // 执行查询指令 JObject data = insProtocol.Query(qIns); if (data == null) data = new JObject(); HxTcpHandler.ReplyFinishMessage(qIns.Message,data); } } catch (Exception ex) { HxTcpHandler.ReplyFailedMessage(qIns.Message, new JObject(), "ERROR", qIns.InsName+" error", 4); } }*/ public InstructionManager() { //q_Instructions = new ConcurrentQueue(); insProtocol = new InsProtocol(); // 启动定时器,每100ms查看一次查询队列中是否有新的查询任务 //qTimer = new System.Threading.Timer(QueueObserver, null, 0, 100); } public void OnConnect(bool isConnect) { insProtocol.OnConnect(isConnect); } /// /// 当任务指令完成时调用该函数反馈给客户端 /// /// 任务产生的数据 /// 任务完成时的状态 public void OnTaskFinish(TaskInstruction tIns, JObject data, int status) { if (tIns != null) { if (status == HxMessage.METHOD_STATUS_COMPLETED) { tIns.Finish(); // 返回任务结束信息 HxTcpHandler.ReplyFinishMessage( tIns.Message, data); } else { tIns.Abort(); HxTcpHandler.ReplyFailedMessage(tIns.Message,data,"EC-00-000", "OnTaskFinish status=failed"); } } } /// /// 当任务指令完成时调用该函数反馈给客户端 /// /// 任务产生的数据 /// 任务完成时的状态 public void OnTaskAbort(TaskInstruction tIns, string errCode, string errString) { if (tIns != null) { tIns.Abort(); HxTcpHandler.ReplyFailedMessage(tIns.Message, ResponseMessagePackage.NullData, "EC-00-000", errString); } } /// /// 设置当前设备的查任务指令 /// /// 任务指令 /// 上一个任务指令还未完成 public void Add(TaskInstruction tIns) { // 当前没有任务指令的时候 //if (t_Instrction == null) //{ // t_Instrction = tIns; //} // 当前有任务指令的时候,需要判断该任务是否已完成 //else { string msg = string.Format("收到指令:{0},{1}", tIns.InsName, tIns.InsId); LogConstant.logger.Print(msg); //// 如果任务准备进行或正在进行中,则抛出任务冲突的错误 //if (t_Instrction.Status == TaskInstruction.TASKSTAT_Scheduled || // t_Instrction.Status == TaskInstruction.TASKSTAT_InProgress) // throw new TaskUncompletedException( // string.Format("执行冲突:任务\"{0}:{1}\"正在运行中", t_Instrction.InsName, t_Instrction.InsId)); //// 如果设备处于TASKSTAT_Completed, TASKSTAT_Failed或TASKSTAT_Cancel状态,则重新将其设为准备态 //else { //t_Instrction = tIns; //t_Instrction.Standby(); } } // 异步执行任务 insProtocol.AsyncTask(ref tIns, OnTaskFinish, OnTaskAbort); } /// /// 设置当前设备的查询指令 /// /// 查询指令 public void Add(QueryInstruction qIns) { lock (qryLock) { //q_Instructions.Enqueue(qIns); } } /// /// 设置当前设备的错误处理指令 /// /// 错误处理指令 /// 上一个任务指令还未完成 public void Add(TroubleshootInstruction tsIns) { // 只有在当前任务存在,且当前任务正在执行过程中,且当前任务与错误处理的ID相同的情况下 if (t_Instrction == null) { LogConstant.logger.Print("没有前置错误可以处理"); return; } if (t_Instrction.Status != TaskInstruction.TASKSTAT_InProgress) { LogConstant.logger.Print(string.Format("任务状态不符合错误处理要求,当前状态为:{0}", t_Instrction.Status)); return; } if (!tsIns.InsId.Equals(t_Instrction.InsId)) { LogConstant.logger.Print(string.Format("任务ID不一致,当前需要处理的任务ID为:{0}", t_Instrction.InsId)); return; } if (!t_Instrction.ErrorHandler.MatchTSCode(tsIns.TSCode)) { LogConstant.logger.Print(string.Format("错误处理方式{0}不符合要求", tsIns.TSCode)); return; } LogConstant.logger.Print(string.Format("开始处理错误,TS Code={0}", tsIns.TSCode)); t_Instrction.ErrorHandler.ReplyAsync(tsIns.TSCode); } } }