using Newtonsoft.Json.Linq;
|
using Sodao.FastSocket.Server;
|
using Sodao.FastSocket.Server.Messaging;
|
using Sodao.FastSocket.SocketBase;
|
using System;
|
using System.Collections.Generic;
|
using System.Configuration;
|
using System.IO;
|
using System.Reflection;
|
using XImaging.Automation.Library.HxDriverLib;
|
using XImaging.Automation.Service.Interface;
|
|
namespace XImaging.Automation.Service
|
{
|
class ResponseMessagePackage
|
{
|
public static JObject NullData
|
{
|
get
|
{
|
return JObject.FromObject(new { });
|
}
|
}
|
|
public static JObject FormStorageInfoData(int m_stack, int m_level, string m_barcode)
|
{
|
return JObject.FromObject(
|
new
|
{
|
stack = m_stack,
|
level = m_level,
|
barcode = m_barcode
|
});
|
}
|
}
|
|
public class HxTcpHandler
|
{
|
/// <summary>
|
/// //主控连接句柄
|
/// </summary>
|
private Dictionary<long, IConnection> m_mainConnection = new Dictionary<long, IConnection>();
|
private static HxTcpHandler m_instance = null;
|
private System.Timers.Timer timer = new System.Timers.Timer();
|
|
private string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
|
private HxTcpHandler()
|
{
|
MessageSection section = ConfigurationManager.GetSection("messages") as MessageSection;
|
|
if (section.Heartbeat.Enabled)
|
{
|
timer.Interval = 5000;
|
timer.Elapsed += (s, e1) =>
|
{
|
CheckConnectAlive(section.Heartbeat.Timeout);
|
};
|
timer.Start();
|
}
|
}
|
|
private void CheckConnectAlive(int timeout)
|
{
|
if (m_mainConnection.Count > 0)
|
{
|
try
|
{
|
foreach (var item in m_mainConnection)
|
{
|
if ((DateTime.UtcNow - item.Value.LatestActiveTime).Seconds > timeout)
|
{
|
LogConstant.logger.Print("[CheckConnectAlive 心跳包超时]");
|
Discard(item.Key);
|
}
|
}
|
}
|
catch { }
|
}
|
}
|
|
|
/// <summary>
|
/// 获取实例
|
/// </summary>
|
/// <returns></returns>
|
public static HxTcpHandler GetInstance()
|
{
|
if (m_instance == null)
|
m_instance = new HxTcpHandler();
|
|
return HxTcpHandler.m_instance;
|
}
|
|
/// <summary>
|
/// 当前是否有客户端连接
|
/// </summary>
|
public bool isConnected { set; get; }
|
|
/// <summary>
|
/// 连接ID
|
/// </summary>
|
|
public bool Contains(long ConnectionID)
|
{
|
return this.m_mainConnection.ContainsKey(ConnectionID);
|
}
|
|
/// <summary>
|
/// 连接地址
|
/// </summary>
|
public string Address(long id)
|
{
|
return this.m_mainConnection[id].RemoteEndPoint.ToString();
|
}
|
|
/// <summary>
|
/// 保持一个新的连接
|
/// </summary>
|
/// <param name="connection"></param>
|
public void Hold(IConnection connection)
|
{
|
this.m_mainConnection.Add(connection.ConnectionID, connection);
|
this.m_mainConnection[connection.ConnectionID].BeginReceive();
|
//UpdateLocalCache();
|
}
|
|
private void UpdateLocalCache()
|
{
|
string remoteEPs = "";
|
foreach(IConnection conns in this.m_mainConnection.Values)
|
{
|
remoteEPs += conns.RemoteEndPoint + "\r\n";
|
}
|
FileStream fs = new FileStream(Path.Combine(appPath, "biosen_conns.dat"), FileMode.Create);
|
StreamWriter sw = new StreamWriter(fs);
|
sw.Write(remoteEPs);
|
sw.Flush();
|
sw.Close();
|
fs.Close();
|
}
|
|
/// <summary>
|
/// 断开时丢弃当前连接
|
/// </summary>
|
public void Discard(long id)
|
{
|
this.m_mainConnection[id].BeginDisconnect();
|
while (this.m_mainConnection[id].Active)
|
{
|
System.Threading.Thread.Sleep(200);
|
}
|
this.m_mainConnection.Remove(id);
|
//UpdateLocalCache();
|
}
|
|
public static bool Empty()
|
{
|
return m_instance.m_mainConnection.Count == 0;
|
}
|
|
public static void ReplyHeartBeatMessage(HxMessage message, int From = 0, int simulate=0)
|
{
|
message.Connected = simulate;
|
foreach (var conn in m_instance.m_mainConnection)
|
if (From == 0 || From.Equals(conn.Value.LocalEndPoint.Port))
|
message.Heartbeat(conn.Value);
|
}
|
public static void ReplyHeartBeatGWMessage(HxMessage message, int From = 0)
|
{
|
foreach (var conn in m_instance.m_mainConnection)
|
if (From == 0 || From.Equals(conn.Value.LocalEndPoint.Port))
|
message.HeartbeatGW(conn.Value);
|
}
|
|
public static void ReplyAckMessage(HxMessage message, int From = 0)
|
{
|
foreach (var conn in m_instance.m_mainConnection)
|
{
|
if (From == 0 || From == conn.Value.LocalEndPoint.Port)
|
{
|
LogConstant.logger.Print(string.Format("[Socket][Ack][{1}]回复ACK指令给{0}", conn.Value.RemoteEndPoint, message.MessageID));
|
message.Ack(conn.Value);
|
}
|
}
|
}
|
|
public static void ReplyFinishMessage(HxMessage message, JObject data, int From = 0)
|
{
|
foreach (var conn in m_instance.m_mainConnection)
|
{
|
if (From == 0 || From == conn.Value.LocalEndPoint.Port)
|
{
|
LogConstant.logger.Print(string.Format("[Socket][Finish][{2}]回复Finish指令给{0}, data={1}",
|
conn.Value.RemoteEndPoint, data.ToString(), message.MessageID));
|
message.Finish(conn.Value, data);
|
}
|
}
|
}
|
|
public static void ReplyFailedMessage(HxMessage message, JObject data, string error_code, string error_text, int dealwithtype=0, int troubleshoot=7, int From = 0)
|
{
|
foreach (var conn in m_instance.m_mainConnection)
|
{
|
if (From == 0 || From == conn.Value.LocalEndPoint.Port)
|
{
|
LogConstant.logger.Print(string.Format("[Socket][Failed][{4}]回复Failed指令给{0}, data={1}, error_code={2}, error_text={3}",
|
conn.Value.RemoteEndPoint, data, error_code, error_text, message.MessageID));
|
message.Failed(conn.Value, data, error_code, error_text, dealwithtype, troubleshoot);
|
}
|
}
|
}
|
|
public static void ReplyErrorMessage(HxMessage message, JObject data, string error_code, string error_text, int dealwithtype = 0, int troubleshoot=7, int From = 0)
|
{
|
foreach (var conn in m_instance.m_mainConnection)
|
{
|
if (From == 0 || From == conn.Value.LocalEndPoint.Port)
|
{
|
LogConstant.logger.Print(string.Format("[Socket][Error][{4}]回复Error指令给{0}, data={1}, error_code={2}, error_text={3}",
|
conn.Value.RemoteEndPoint, data, error_code, error_text, message.MessageID));
|
message.Error(conn.Value, data, error_code, error_text, dealwithtype, troubleshoot);
|
}
|
}
|
}
|
}
|
|
public class BiosenSocketService : AbsSocketService<HxMessage>
|
{
|
/// <summary>
|
/// Tcp连接管理
|
/// </summary>
|
private HxTcpHandler m_mainTcpListener = HxTcpHandler.GetInstance();
|
//private IMessageQueueHandler m_handleMQ;
|
private IMessageDispatch m_msgDispatch = MessageDispatch.GetInstance();
|
private string hbLogs = "false";
|
private bool isConnected = false;
|
|
public BiosenSocketService() : base()
|
{
|
hbLogs = ConfigurationManager.AppSettings.Get("HBLogs");
|
//string mq = ConfigurationManager.ConnectionStrings["MessageQueue"].ConnectionString;
|
//if (mq.ToLower().Equals("redis"))
|
//{
|
// m_handleMQ = RedisQueueHandler.GetInstance();
|
//}
|
}
|
|
/// <summary>
|
/// 连接函数
|
/// </summary>
|
/// <param name="connection"></param>
|
public override void OnConnected(IConnection connection)
|
{
|
base.OnConnected(connection);
|
LogConstant.logger.Print("[Socket][Connection]检测到来自" + connection.RemoteEndPoint.ToString() + "的远程连接");
|
|
try
|
{
|
this.m_mainTcpListener.Hold(connection);
|
LogConstant.logger.Print("[Socket][Connection]已连接" + connection.RemoteEndPoint.Address);
|
m_msgDispatch.OnConnect(true);
|
isConnected = true;
|
}
|
catch (Exception ex)
|
{
|
LogConstant.logger.Print("[Socket][Exception]" + ex.ToString());
|
}
|
}
|
|
/// <summary>
|
/// 当连接断开时会调用此方法
|
/// </summary>
|
/// <param name="connection"></param>
|
/// <param name="ex"></param>
|
public override void OnDisconnected(IConnection connection, Exception ex)
|
{
|
base.OnDisconnected(connection, ex);
|
try
|
{
|
if (this.m_mainTcpListener.Contains(connection.ConnectionID))
|
{
|
LogConstant.logger.Print("[Socket][Connection]即将断开连接: " + connection.RemoteEndPoint.ToString() +
|
" ConnectionID = " + connection.ConnectionID.ToString());
|
this.m_mainTcpListener.Discard(connection.ConnectionID);
|
LogConstant.logger.Print("[Socket][Connection]已断开与" + connection.RemoteEndPoint.ToString() + "的远程连接");
|
|
m_msgDispatch.OnConnect(false);
|
isConnected = false;
|
|
}
|
}
|
catch (Exception e)
|
{
|
LogConstant.logger.Print("[Socket][Exception]" + e.ToString());
|
}
|
}
|
|
|
/// <summary>
|
/// 接收函数
|
/// </summary>
|
/// <param name="connection"></param>
|
/// <param name="message"></param>
|
///
|
public override void OnReceived(IConnection connection, HxMessage message)
|
{
|
try
|
{
|
base.OnReceived(connection, message);
|
if (message.MessageType == HxMessage.MESSAGE_TYPE_HEARTBEAT)
|
{
|
//LogConstant.logger.Print(string.Format("[Socket][HeartBeat][{0}]收到来自{1}的心跳消息", message.MessageID, connection.RemoteEndPoint));
|
HxTcpHandler.ReplyHeartBeatMessage(message, connection.LocalEndPoint.Port);
|
if(!isConnected)
|
{
|
m_msgDispatch.OnConnect(true);
|
isConnected = true;
|
}
|
}
|
else
|
{
|
if (message.MessageType == HxMessage.MESSAGE_TYPE_HEARTBEAT)
|
{
|
if(!string.IsNullOrEmpty(hbLogs) && hbLogs == "true")
|
LogConstant.logger.Print(string.Format("[Socket][Instruction][{0}]收到来自{1}的心跳包: {2}", message.MessageID, connection.RemoteEndPoint, message.OriginJSON));
|
}
|
else
|
{
|
LogConstant.logger.Print(string.Format("[Socket][Instruction][{0}]收到来自{1}指令消息: {2}", message.MessageID, connection.RemoteEndPoint, message.OriginJSON));
|
}
|
// 向消息队列推送请求
|
//m_handleMQ.PushMessage(message, connection.LocalEndPoint.Port);
|
m_msgDispatch.Parse(message);
|
}
|
}
|
catch (System.Exception ex)
|
{
|
LogConstant.logger.Print("[Exception]" + ex.ToString());
|
}
|
|
}
|
|
/// <summary>
|
/// 当发生错误时会调用此方法
|
/// </summary>
|
/// <param name="connection"></param>
|
/// <param name="ex"></param>
|
public override void OnException(IConnection connection, Exception ex)
|
{
|
base.OnException(connection, ex);
|
LogConstant.logger.Print("[Socket][Error]接收消息错误: " + ex.ToString());
|
}
|
}
|
}
|