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