using Newtonsoft.Json;
|
using Newtonsoft.Json.Linq;
|
using System;
|
using System.Text;
|
|
|
namespace Sodao.FastSocket.Server.Messaging
|
{
|
/// <summary>
|
///
|
/// </summary>
|
public sealed class HxMessage : Messaging.IMessage, XImaging.Automation.Library.HxDriverLib.Messaging.IMessage
|
{
|
static private readonly string ENDOP = "#!HxSEP!#";
|
|
#region 消息类型定义
|
/// <summary>
|
/// 消息类型-1: 网关心跳包
|
/// </summary>
|
public static int MESSAGE_TYPE_HEARTBEAT_GW { get; } = -1;
|
|
/// <summary>
|
/// 消息类型0: 心跳包
|
/// </summary>
|
public static int MESSAGE_TYPE_HEARTBEAT { get; } = 0;
|
/// <summary>
|
/// 消息类型1:方法消息(延迟返回消息)
|
/// </summary>
|
public static int MESSAGE_TYPE_TASK { get; } = 1;
|
/// <summary>
|
/// 消息类型2:查询方法消息(即时返回消息)
|
/// </summary>
|
public static int MESSAGE_TYPE_QUERY { get; } = 2;
|
/// <summary>
|
/// 消息类型3:错误处理消息(无返回消息)
|
/// </summary>
|
public static int MESSAGE_TYPE_TROUBLESHOOT { get; } = 3;
|
/// <summary>
|
/// 消息类型4:确认消息
|
/// </summary>
|
public static int MESSAGE_TYPE_ACK { get; } = 4;
|
/// <summary>
|
/// 消息类型5:完成消息
|
/// </summary>
|
public static int MESSAGE_TYPE_FINISH { get; } = 5;
|
/// <summary>
|
/// 消息类型6:错误消息(可被代替,兼容v1.6版本)
|
/// </summary>
|
public static int MESSAGE_TYPE_ERROR { get; } = 6;
|
#endregion
|
|
#region 方法状态定义
|
/// <summary>
|
/// 方法状态0:准备执行(指令队列中)
|
/// </summary>
|
public static int METHOD_STATUS_SCHEDULED { get; } = 0;
|
/// <summary>
|
/// 方法状态1:正在执行
|
/// </summary>
|
public static int METHOD_STATUS_INPROGRES { get; } = 1;
|
/// <summary>
|
/// 方法状态2:执行完成且成功
|
/// </summary>
|
public static int METHOD_STATUS_COMPLETED { get; } = 2;
|
/// <summary>
|
/// 方法状态3:执行完成且失败
|
/// </summary>
|
public static int METHOD_STATUS_FAILED { get; } = 3;
|
/// <summary>
|
/// 方法状态4:该方法在指令队列中被取消
|
/// </summary>
|
public static int METHOD_STATUS_CANCELED { get; } = 4;
|
/// <summary>
|
/// 方法状态4:该方法在指令队列中被取消
|
/// </summary>
|
public static int METHOD_STATUS_ERROR { get; } = 5;
|
#endregion
|
|
#region 私有成员
|
private JObject m_jsonOriginMessage;
|
private string m_strMessageID;
|
private int m_iMessageType;
|
private string m_strMethod;
|
private string m_strEquipmentID;
|
private int m_iEquipmentStatus;
|
private int m_iActualDeviceStatus;
|
private string m_strWorkflowID;
|
private string m_strExperimentID;
|
private JObject m_jsonParameters;
|
private int m_iTroubleshoot;
|
private string m_strDescription;
|
private JObject m_jsonProcessInfo;
|
private int m_iEstimateTime;
|
private int m_iConnected;
|
private int m_iTimeout;
|
private string m_strTimestamp;
|
|
/// <summary>
|
/// 原始消息
|
/// </summary>
|
public JObject OriginJSON { get { return m_jsonOriginMessage; } }
|
|
#endregion
|
/// <summary>
|
/// 消息ID,唯一
|
/// </summary>
|
public string MessageID { get { return m_strMessageID; } }
|
/// <summary>
|
/// 消息类型,见定义
|
/// </summary>
|
public int MessageType { get { return m_iMessageType; } }
|
/// <summary>
|
/// 方法名称
|
/// </summary>
|
public string Method { get { return m_strMethod; } }
|
/// <summary>
|
/// 设备ID
|
/// </summary>
|
public string EquipmentID { get { return m_strEquipmentID; } }
|
|
/// <summary>
|
/// 设备状态
|
/// </summary>
|
public int EquipmentStatus { set { this.m_iEquipmentStatus = value; } get { return m_iEquipmentStatus; } }
|
|
/// <summary>
|
/// 设备状态
|
/// </summary>
|
public int ActualDeviceStatus { set { this.m_iActualDeviceStatus = value; } get { return m_iActualDeviceStatus; } }
|
|
/// <summary>
|
/// 工作流ID
|
/// </summary>
|
public string WorkflowID { set { this.m_strWorkflowID = value; } get { return m_strWorkflowID; } }
|
/// <summary>
|
/// 实验ID
|
/// </summary>
|
public string ExperimentID { get { return m_strExperimentID; } }
|
/// <summary>
|
/// 方法需要的参数
|
/// </summary>
|
public JObject Parameters { get { return m_jsonParameters; } }
|
/// <summary>
|
///
|
/// </summary>
|
public int Troubleshoot { get { return m_iTroubleshoot; } }
|
/// <summary>
|
/// 方法描述文字
|
/// </summary>
|
public string Description { get { return m_strDescription; } }
|
|
/// <summary>
|
/// 任务信息,可以不需要
|
/// </summary>
|
public JObject ProcessInfo { get { return m_jsonProcessInfo; } }
|
|
/// <summary>
|
/// 预估时间,可以不需要
|
/// </summary>
|
public int EstimateTime { get { return m_iEstimateTime; } }
|
|
/// <summary>
|
/// 超时时间,可以不需要
|
/// </summary>
|
public int Timeout { get { return m_iTimeout; } }
|
|
/// <summary>
|
/// 消息生成时间
|
/// </summary>
|
public string Timestamp { get { return m_strTimestamp; } }
|
|
|
/// <summary>
|
/// 消息生成时间
|
/// </summary>
|
public int Connected { set { this.m_iConnected = value; } get { return m_iConnected; } }
|
|
/// <summary>
|
/// 构造类1
|
/// </summary>
|
/// <param name="message"></param>
|
public HxMessage(string message)
|
{
|
JObject obj = (JObject)JsonConvert.DeserializeObject(message);
|
|
this.m_jsonOriginMessage = obj;
|
this.m_strMessageID = obj["message_id"].ToString();
|
this.m_iMessageType = obj.Value<int>("message_type");
|
this.m_strEquipmentID = obj["equipment_id"].ToString();
|
if (this.MessageType == MESSAGE_TYPE_HEARTBEAT)
|
{
|
this.m_iEquipmentStatus = obj.Value<int>("equipment_status");
|
this.m_iActualDeviceStatus = obj.Value<int>("actual_device_status");
|
this.m_strWorkflowID = obj.Value<string>("workflow_id");
|
if (obj.ContainsKey("connected"))
|
this.m_iConnected = obj.Value<int>("connected");
|
else
|
this.m_iConnected = 0;
|
}
|
|
if (this.MessageType != MESSAGE_TYPE_HEARTBEAT && this.MessageType != MESSAGE_TYPE_HEARTBEAT_GW)
|
{
|
this.m_strWorkflowID = obj["workflow_id"].ToString();
|
if (obj.ContainsKey("experiment_id"))
|
this.m_strExperimentID = obj["experiment_id"].ToString();
|
else
|
{
|
this.m_strExperimentID = "Unknown";
|
this.m_jsonOriginMessage.Add("experiment_id", this.m_strExperimentID);
|
}
|
|
this.m_strMethod = obj["method"].ToString();
|
if (obj.ContainsKey("description"))
|
this.m_strDescription = obj["description"].ToString();
|
else
|
this.m_strDescription = "";
|
}
|
|
if (this.MessageType == MESSAGE_TYPE_TASK || this.MessageType == MESSAGE_TYPE_QUERY)
|
{
|
this.m_jsonParameters = (JObject)obj["parameters"];
|
if (obj.ContainsKey("process_info"))
|
this.m_jsonProcessInfo = (JObject)obj["process_info"];
|
else
|
this.m_jsonProcessInfo = JObject.FromObject(new { processId = "", instanceId = "", taskId = "" });
|
|
if (obj.ContainsKey("estimate_time"))
|
this.m_iEstimateTime = obj.Value<int>("estimate_time");
|
else
|
this.m_iEstimateTime = 5000;
|
|
if (obj.ContainsKey("timeout"))
|
this.m_iTimeout = obj.Value<int>("timeout");
|
else
|
this.m_iTimeout = this.m_iEstimateTime * 2;
|
}
|
else
|
{
|
this.m_jsonParameters = null;
|
this.m_jsonProcessInfo = null;
|
}
|
if (this.MessageType == MESSAGE_TYPE_TROUBLESHOOT)
|
this.m_iTroubleshoot = obj.Value<int>("troubleshoot");
|
else
|
this.m_iTroubleshoot = 0;
|
|
this.m_strTimestamp = obj["timestamp"].ToString();
|
}
|
|
public void Heartbeat(SocketBase.IConnection connection)
|
{
|
if (connection == null) throw new ArgumentNullException("connection");
|
connection.BeginSend(ToHeartbeatPacket(
|
this.MessageID,
|
MESSAGE_TYPE_HEARTBEAT,
|
this.EquipmentID,
|
this.EquipmentStatus,
|
this.ActualDeviceStatus,
|
this.WorkflowID,
|
this.Connected));
|
}
|
public void HeartbeatGW(SocketBase.IConnection connection)
|
{
|
if (connection == null) throw new ArgumentNullException("connection");
|
connection.BeginSend(ToHeartbeatPacket(
|
this.MessageID,
|
MESSAGE_TYPE_HEARTBEAT_GW,
|
this.EquipmentID,
|
this.EquipmentStatus,
|
this.ActualDeviceStatus,
|
this.WorkflowID,
|
this.Connected));
|
}
|
|
#region Public Methods
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="connection"></param>
|
public void Ack(SocketBase.IConnection connection)
|
{
|
if (connection == null) throw new ArgumentNullException("connection");
|
connection.BeginSend(ToAckPacket(
|
this.MessageID,
|
MESSAGE_TYPE_ACK,
|
this.Method,
|
this.EquipmentID,
|
this.WorkflowID,
|
this.ExperimentID,
|
this.m_jsonProcessInfo));
|
}
|
public void Error(SocketBase.IConnection connection, JObject data, string error_code, string error_text, int dealwithtype, int troubleshoot)
|
{
|
if (connection == null) throw new ArgumentNullException("connection");
|
connection.BeginSend(ToErrorPacket(
|
this.MessageID,
|
MESSAGE_TYPE_TROUBLESHOOT,
|
this.Method,
|
this.EquipmentID,
|
this.WorkflowID,
|
this.ExperimentID,
|
data,
|
this.m_jsonProcessInfo,
|
METHOD_STATUS_ERROR,
|
error_code,
|
error_text,
|
dealwithtype,
|
troubleshoot));
|
}
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="connection"></param>
|
/// <param name="data"></param>
|
public void Finish(SocketBase.IConnection connection, JObject data)
|
{
|
if (connection == null) throw new ArgumentNullException("connection");
|
connection.BeginSend(ToFinishPacket(
|
this.MessageID,
|
MESSAGE_TYPE_FINISH,
|
this.Method,
|
this.EquipmentID,
|
this.WorkflowID,
|
this.ExperimentID,
|
data,
|
this.m_jsonProcessInfo,
|
METHOD_STATUS_COMPLETED,
|
"", "", 0, 0
|
));
|
}
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="connection"></param>
|
/// <param name="data"></param>
|
/// <param name="error_code"></param>
|
/// <param name="error_text"></param>
|
/// <param name="troubleshoot"></param>
|
public void Failed(SocketBase.IConnection connection, JObject data, string error_code, string error_text, int dealwithtype, int troubleshoot)
|
{
|
if (connection == null) throw new ArgumentNullException("connection");
|
connection.BeginSend(ToFinishPacket(
|
this.MessageID,
|
MESSAGE_TYPE_FINISH,
|
this.Method,
|
this.EquipmentID,
|
this.WorkflowID,
|
this.ExperimentID,
|
data,
|
this.m_jsonProcessInfo,
|
METHOD_STATUS_FAILED,
|
error_code,
|
error_text,
|
dealwithtype,
|
troubleshoot
|
));
|
}
|
static public SocketBase.Packet ToHeartbeatPacket(
|
string p_MessageID,
|
int p_MessageType,
|
string p_EquipmentID,
|
int p_EquipmentStatus,
|
int p_ActualDeviceStatus,
|
string p_WorkflowId,
|
int p_Connected)
|
{
|
JObject obj = JObject.FromObject(
|
new
|
{
|
message_id = p_MessageID,
|
message_type = p_MessageType,
|
equipment_id = p_EquipmentID,
|
equipment_status = p_EquipmentStatus,
|
actual_device_status = p_ActualDeviceStatus,
|
workflow_id = p_WorkflowId,
|
connected = p_Connected,
|
timestamp = DateTime.Now
|
}
|
);
|
string trims = obj.ToString().Replace("\r\n", "");
|
return new SocketBase.Packet(Encoding.UTF8.GetBytes(string.Concat(trims, ENDOP)));
|
}
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="p_MessageID"></param>
|
/// <param name="p_MessageType"></param>
|
/// <param name="p_Method"></param>
|
/// <param name="p_EquipmentID"></param>
|
/// <param name="p_WorkflowID"></param>
|
/// <returns></returns>
|
static public SocketBase.Packet ToAckPacket(
|
string p_MessageID,
|
int p_MessageType,
|
string p_Method,
|
string p_EquipmentID,
|
string p_WorkflowID,
|
string p_ExperimentID,
|
JObject p_ProcessInfo)
|
{
|
JObject obj = JObject.FromObject(
|
new
|
{
|
message_id = p_MessageID,
|
message_type = p_MessageType,
|
method = p_Method,
|
equipment_id = p_EquipmentID,
|
workflow_id = p_WorkflowID,
|
experiment_id = p_ExperimentID,
|
process_info = p_ProcessInfo,
|
timestamp = DateTime.Now
|
}
|
);
|
string trims = obj.ToString().Replace("\r\n", "");
|
return new SocketBase.Packet(Encoding.UTF8.GetBytes(string.Concat(trims, ENDOP)));
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="p_MessageID"></param>
|
/// <param name="p_MessageType"></param>
|
/// <param name="p_Method"></param>
|
/// <param name="p_EquipmentID"></param>
|
/// <param name="p_WorkflowID"></param>
|
/// <param name="p_data"></param>
|
/// <param name="p_MethodStatus"></param>
|
/// <param name="p_ErrorCode"></param>
|
/// <param name="p_ErrorText"></param>
|
/// <param name="p_Troubleshoot"></param>
|
/// <returns></returns>
|
static public SocketBase.Packet ToFinishPacket(
|
string p_MessageID,
|
int p_MessageType,
|
string p_Method,
|
string p_EquipmentID,
|
string p_WorkflowID,
|
string p_ExperimentID,
|
JObject p_data,
|
JObject p_ProcessInfo,
|
int p_MethodStatus,
|
string p_ErrorCode,
|
string p_ErrorText,
|
int p_Troubleshoot,
|
int p_Dealwithtype)
|
{
|
JObject obj = JObject.FromObject(
|
new
|
{
|
message_id = p_MessageID,
|
message_type = p_MessageType,
|
method = p_Method,
|
equipment_id = p_EquipmentID,
|
workflow_id = p_WorkflowID,
|
experiment_id = p_ExperimentID,
|
data = p_data,
|
process_info = p_ProcessInfo,
|
method_status = p_MethodStatus,
|
error = new
|
{
|
error_code = p_ErrorCode,//by N
|
error_text = p_ErrorText,
|
troubleshoot = p_Troubleshoot,
|
dealwithtype= p_Dealwithtype
|
},
|
troubleshoot= p_Troubleshoot, //by N
|
errorSource= 0,//by N
|
timestamp = DateTime.Now
|
}
|
);
|
string trims = obj.ToString().Replace("\r\n", "");
|
return new SocketBase.Packet(Encoding.UTF8.GetBytes(string.Concat(trims, ENDOP)));
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="p_MessageID"></param>
|
/// <param name="p_MessageType"></param>
|
/// <param name="p_Method"></param>
|
/// <param name="p_EquipmentID"></param>
|
/// <param name="p_WorkflowID"></param>
|
/// <param name="p_data"></param>
|
/// <param name="p_MethodStatus"></param>
|
/// <param name="p_ErrorCode"></param>
|
/// <param name="p_ErrorText"></param>
|
/// <param name="p_Troubleshoot"></param>
|
/// <returns></returns>
|
static public SocketBase.Packet ToErrorPacket(
|
string p_MessageID,
|
int p_MessageType,
|
string p_Method,
|
string p_EquipmentID,
|
string p_WorkflowID,
|
string p_ExperimentID,
|
JObject p_data,
|
JObject p_ProcessInfo,
|
int p_MethodStatus,
|
string p_ErrorCode,
|
string p_ErrorText,
|
int p_Dealwithtype,
|
int p_Troubleshoot)
|
{
|
JObject obj = JObject.FromObject(
|
new
|
{
|
message_id = p_MessageID,
|
message_type = p_MessageType,
|
method = p_Method,
|
equipment_id = p_EquipmentID,
|
workflow_id = p_WorkflowID,
|
experiment_id = p_ExperimentID,
|
data = p_data,
|
process_info = p_ProcessInfo,
|
method_status = p_MethodStatus,
|
errorSource = 2,
|
error = new
|
{
|
error_code = p_ErrorCode,
|
error_text = p_ErrorText,
|
troubleshoot = p_Troubleshoot,
|
dealwithtype = p_Dealwithtype,
|
},
|
timestamp = DateTime.Now
|
}
|
);
|
string trims = obj.ToString().Replace("\r\n", "");
|
return new SocketBase.Packet(Encoding.UTF8.GetBytes(string.Concat(trims, ENDOP)));
|
}
|
#endregion
|
}
|
|
}
|