using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Text;
namespace Sodao.FastSocket.Server.Messaging
{
///
///
///
public sealed class HxMessage : Messaging.IMessage, XImaging.Automation.Library.HxDriverLib.Messaging.IMessage
{
static private readonly string ENDOP = "#!HxSEP!#";
#region 消息类型定义
///
/// 消息类型-1: 网关心跳包
///
public static int MESSAGE_TYPE_HEARTBEAT_GW { get; } = -1;
///
/// 消息类型0: 心跳包
///
public static int MESSAGE_TYPE_HEARTBEAT { get; } = 0;
///
/// 消息类型1:方法消息(延迟返回消息)
///
public static int MESSAGE_TYPE_TASK { get; } = 1;
///
/// 消息类型2:查询方法消息(即时返回消息)
///
public static int MESSAGE_TYPE_QUERY { get; } = 2;
///
/// 消息类型3:错误处理消息(无返回消息)
///
public static int MESSAGE_TYPE_TROUBLESHOOT { get; } = 3;
///
/// 消息类型4:确认消息
///
public static int MESSAGE_TYPE_ACK { get; } = 4;
///
/// 消息类型5:完成消息
///
public static int MESSAGE_TYPE_FINISH { get; } = 5;
///
/// 消息类型6:错误消息(可被代替,兼容v1.6版本)
///
public static int MESSAGE_TYPE_ERROR { get; } = 6;
#endregion
#region 方法状态定义
///
/// 方法状态0:准备执行(指令队列中)
///
public static int METHOD_STATUS_SCHEDULED { get; } = 0;
///
/// 方法状态1:正在执行
///
public static int METHOD_STATUS_INPROGRES { get; } = 1;
///
/// 方法状态2:执行完成且成功
///
public static int METHOD_STATUS_COMPLETED { get; } = 2;
///
/// 方法状态3:执行完成且失败
///
public static int METHOD_STATUS_FAILED { get; } = 3;
///
/// 方法状态4:该方法在指令队列中被取消
///
public static int METHOD_STATUS_CANCELED { get; } = 4;
///
/// 方法状态4:该方法在指令队列中被取消
///
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;
///
/// 原始消息
///
public JObject OriginJSON { get { return m_jsonOriginMessage; } }
#endregion
///
/// 消息ID,唯一
///
public string MessageID { get { return m_strMessageID; } }
///
/// 消息类型,见定义
///
public int MessageType { get { return m_iMessageType; } }
///
/// 方法名称
///
public string Method { get { return m_strMethod; } }
///
/// 设备ID
///
public string EquipmentID { get { return m_strEquipmentID; } }
///
/// 设备状态
///
public int EquipmentStatus { set { this.m_iEquipmentStatus = value; } get { return m_iEquipmentStatus; } }
///
/// 设备状态
///
public int ActualDeviceStatus { set { this.m_iActualDeviceStatus = value; } get { return m_iActualDeviceStatus; } }
///
/// 工作流ID
///
public string WorkflowID { set { this.m_strWorkflowID = value; } get { return m_strWorkflowID; } }
///
/// 实验ID
///
public string ExperimentID { get { return m_strExperimentID; } }
///
/// 方法需要的参数
///
public JObject Parameters { get { return m_jsonParameters; } }
///
///
///
public int Troubleshoot { get { return m_iTroubleshoot; } }
///
/// 方法描述文字
///
public string Description { get { return m_strDescription; } }
///
/// 任务信息,可以不需要
///
public JObject ProcessInfo { get { return m_jsonProcessInfo; } }
///
/// 预估时间,可以不需要
///
public int EstimateTime { get { return m_iEstimateTime; } }
///
/// 超时时间,可以不需要
///
public int Timeout { get { return m_iTimeout; } }
///
/// 消息生成时间
///
public string Timestamp { get { return m_strTimestamp; } }
///
/// 消息生成时间
///
public int Connected { set { this.m_iConnected = value; } get { return m_iConnected; } }
///
/// 构造类1
///
///
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("message_type");
this.m_strEquipmentID = obj["equipment_id"].ToString();
if (this.MessageType == MESSAGE_TYPE_HEARTBEAT)
{
this.m_iEquipmentStatus = obj.Value("equipment_status");
this.m_iActualDeviceStatus = obj.Value("actual_device_status");
this.m_strWorkflowID = obj.Value("workflow_id");
if (obj.ContainsKey("connected"))
this.m_iConnected = obj.Value("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("estimate_time");
else
this.m_iEstimateTime = 5000;
if (obj.ContainsKey("timeout"))
this.m_iTimeout = obj.Value("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("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
///
///
///
///
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));
}
///
///
///
///
///
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
));
}
///
///
///
///
///
///
///
///
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)));
}
///
///
///
///
///
///
///
///
///
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)));
}
///
///
///
///
///
///
///
///
///
///
///
///
///
///
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)));
}
///
///
///
///
///
///
///
///
///
///
///
///
///
///
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
}
}