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
{
///
/// //主控连接句柄
///
private Dictionary m_mainConnection = new Dictionary();
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 { }
}
}
///
/// 获取实例
///
///
public static HxTcpHandler GetInstance()
{
if (m_instance == null)
m_instance = new HxTcpHandler();
return HxTcpHandler.m_instance;
}
///
/// 当前是否有客户端连接
///
public bool isConnected { set; get; }
///
/// 连接ID
///
public bool Contains(long ConnectionID)
{
return this.m_mainConnection.ContainsKey(ConnectionID);
}
///
/// 连接地址
///
public string Address(long id)
{
return this.m_mainConnection[id].RemoteEndPoint.ToString();
}
///
/// 保持一个新的连接
///
///
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();
}
///
/// 断开时丢弃当前连接
///
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
{
///
/// Tcp连接管理
///
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();
//}
}
///
/// 连接函数
///
///
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());
}
}
///
/// 当连接断开时会调用此方法
///
///
///
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());
}
}
///
/// 接收函数
///
///
///
///
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());
}
}
///
/// 当发生错误时会调用此方法
///
///
///
public override void OnException(IConnection connection, Exception ex)
{
base.OnException(connection, ex);
LogConstant.logger.Print("[Socket][Error]接收消息错误: " + ex.ToString());
}
}
}