using DataEntity.Sockets.Base;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using XCommon.Log;
using XCoreBLL;
using XHandler.Class.DataEx;
using XImagingXhandler.XDAL;
using static System.Net.Mime.MediaTypeNames;
namespace HxSocket
{
///
/// 通讯客户端
///
public class HxSocketClient
{
#region 变量
///
/// 用于锁定m_listRecvMessage
///
private object m_objListLock = new object();
///
/// 通讯类
///
private Socket m_socket = null;
private object m_socketLockObj = new object();
///
/// 接受数据线程
///
private Thread recvThread = null;
///
/// 检测服务端断连定时器
///
private System.Threading.Timer m_connectTimer = null;
///
/// IP
///
private string m_ip;
///
/// Port
///
private int m_port;
///
/// 缓存所有的消息队列,同时可以收到多条消息
///
private List m_listRecvMessage = new List();
///
/// 一次拍照命令接收消息数
///
private int m_countOfOnce = 0;
#endregion
#region 常量
public const string CMD_END = "#!HxSEP!#";
#endregion
///
/// 构造函数
///
///
///
public HxSocketClient(string ip, int port)
{
this.m_ip = ip;
this.m_port = port;
}
///
/// 连接服务端
///
///
///
///
public bool connectServer(string ip, int port)
{
bool bResult = false;
try
{
// 创建Socket实例
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 连接服务器
m_socket.Connect(ip, port);
if (m_socket.Connected)
{
bResult = true;
LoggerSocketHelper.InfoLog(string.Format("[HxSocketClient][connectServer]: ip:{0},port:{1}连接成功!", ip, port));
StartRecvThread();
}
else
{
LoggerSocketHelper.ErrorLog(string.Format("[HxSocketClient][connectServer]: ip:{0},port:{1}连接失败!", ip, port));
}
}
catch (System.Net.Sockets.SocketException ex)
{
LoggerSocketHelper.ErrorLog(string.Format("[HxSocketClient][connectServer]: ip:{0},port:{1}连接失败!", ip, port));
}
finally
{
if (m_connectTimer == null)
{
// 连接离心机定时器,每500ms查看一次连接状态
m_connectTimer = new System.Threading.Timer(ConnectTimer, null, 0, 1000);
}
}
return bResult;
}
///
/// 检测服务端断连定时器
///
///
private void ConnectTimer(object state)
{
lock (m_socketLockObj)
{
try
{
// m_bIsNetConnect &&
if (IsConnect())
{
return;
}
LoggerSocketHelper.DebugLog(string.Format("[HxSocketClient]: 与ip:{0}, port:{1}断开了连接,开始重连", m_ip, m_port));
// 断开连接
CloseConnect();
// 关闭接受数据线程
CloceRecvThread();
// 连接服务端
connectServer(m_ip, m_port);
//m_bIsNetConnect = false;
//IPAddress ipAddress = IPAddress.Parse(m_strIP);
//LogConstant.logger.Print("开始与离心机PLC连接");
//m_client.Connect(ipAddress, m_nPort);
//// 创建一个client连接
//ModbusMaster = ModbusIpMaster.CreateIp(m_client);
//// 设置读取超时时间
//ModbusMaster.Transport.ReadTimeout = m_nTimeOut;
//ModbusMaster.Transport.WriteTimeout = m_nTimeOut;
//ModbusMaster.Transport.Retries = 0;
//LogConstant.logger.Print("离心机PLC已连接");
//m_bIsNetConnect = true;
}
catch (Exception ex)
{
LoggerSocketHelper.ErrorLog("ERROR:", ex);
// 断开连接
CloseConnect();
// 关闭接受数据线程
CloceRecvThread();
}
}
}
///
/// 拍照
///
/// 发送的数据
/// 是否输出日志:心跳=false,不输出
///
public List SendMessage(string data, bool isOutLog = true)
{
List strResult = new List();
try
{
HxRequestBase reqData = JsonConvert.DeserializeObject(data);
// 发送请求数据
string message = data + CMD_END;
byte[] msg = Encoding.ASCII.GetBytes(message);
if (m_socket != null && m_socket.Connected)
{
int bytesSent = m_socket.Send(msg);
if (isOutLog)
{
LoggerSocketHelper.InfoLog(string.Format("[SendMessage]:向照相系统({0})发送数据成功:{1}{2}", m_socket.RemoteEndPoint.ToString(), Environment.NewLine, message));
}
}
else
{
LoggerSocketHelper.InfoLog(string.Format("[SendMessage]: m_socket == null || !m_socket.Connected, 消息不发送"));
}
// Task、Quary
if (reqData.message_type == 1 ||
reqData.message_type == 2)
{
while (m_countOfOnce < 2)
{
Thread.Sleep(1 * 200);
}
m_countOfOnce = 0;
// 获取应答
for (int i = 0; i < m_listRecvMessage.Count; i++)
{
strResult.Add(m_listRecvMessage[i]);
}
m_listRecvMessage.Clear();
}
}
catch (Exception ex)
{
LoggerSocketHelper.ErrorLog("ERROR:", ex);
}
finally
{
//LoggerSocketHelper.InfoLog(string.Format("[SendMessage]: Finished."));
}
return strResult;
}
///
/// 构建成像板位松开状态消息
///
///
///
///
public string CreateSendOpenCraw(MethodMsg methodMsg)
{
string strCommand = string.Empty;
string strJson = "";
strJson = "{" + "message_id:\"" + Guid.NewGuid().ToString() +
"\",message_type:" + methodMsg.methodmsg_type +
",method:\"" + methodMsg.methodmsg_methodname + "\"" +
",equipment_id:\"" + methodMsg.methodmsg_machine_id + "\"" +
",workflow_id:\"\"" +
",experiment_id:\"" + methodMsg.methodmsg_experiment_id +
"\",parameters:" +
"{" +
//"open:" + methodMsg.troubleshoot.ToString() + "" +
"}" +
",process_info:{}" +
",estimate_time:5" +
",timeout:60" +
",description:\"NO DESC\"" +
",timestamp:\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\"}";
strCommand = strJson;
return strCommand;
}
///
/// 向中控发送错误或提示信息
///
/// 错误或提示信息字串
/// 是否中控远程
public void sendmessageError(string data, bool isRemotingOper)
{
try
{
// 发送请求数据
string message = data;
byte[] msg = Encoding.ASCII.GetBytes(message);
if (isRemotingOper)
{
int bytesSent = m_socket.Send(msg);
LoggerSocketHelper.InfoLog("send data is successful.[data:" + message + "]");
}
}
catch (Exception ex)
{
LoggerSocketHelper.ErrorLog("ERROR:", ex);
}
}
public string CreateSendMsgContent(MethodMsg methodMsg, bool finished)
{
string strCommand = string.Empty;
string strJson = "";
if (finished)
{
strJson = "{" + "message_id:\"" + Guid.NewGuid().ToString() +
"\",message_type:" + methodMsg.methodmsg_type +
",method:\"" + methodMsg.methodmsg_methodname + "\"" +
",equipment_id:\"" + methodMsg.methodmsg_machine_id + "\"" +
",workflow_id:\"\"" +
",experiment_id:\"" + methodMsg.methodmsg_experiment_id +
",dealwithtype:" + methodMsg.slovetype.ToString() +
",data:\"\"" +
",process_info:{}" +
",estimate_time:5" +
",timeout:60" +
",description:\"NO DESC\"" +
",timestamp:\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\"}";
}
else
{
strJson = "{" + "message_id:\"" + Guid.NewGuid().ToString() +
"\",message_type:" + methodMsg.methodmsg_type +
",method:\"" + methodMsg.methodmsg_methodname + "\"" +
",equipment_id:\"" + methodMsg.methodmsg_machine_id + "\"" +
",workflow_id:\"\"" +
",experiment_id:\"" + methodMsg.methodmsg_experiment_id +
"\",error:" +
"{" +
"error_code:\"" + methodMsg.error_code + "\"" +
",error_text:\"" + methodMsg.error_text + "\"" +
",troubleshoot:" + methodMsg.troubleshoot.ToString() + "" +
",dealwithtype:" + methodMsg.slovetype.ToString() +
"}" +
",data:\"\"" +
",process_info:{}" +
",estimate_time:5" +
",timeout:60" +
",description:\"NO DESC\"" +
",timestamp:\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\"}";
}
strCommand = strJson;
return strCommand;
}
///
/// 断开连接
///
public void CloseConnect()
{
try
{
if (m_socket != null)
{
// 关闭Socket实例
m_socket.Shutdown(SocketShutdown.Both);
m_socket.Close();
m_socket.Dispose();
m_socket = null;
}
}
catch (Exception ex)
{
LoggerSocketHelper.ErrorLog("[HxSocketClient][CloseConnect]:ERROR:", ex);
}
}
///
/// 收到的消息添加到list中
///
///
private void AddMessageToList(string strRecvMessage)
{
if (strRecvMessage.Length > 0)
{
// 防止两条命令合并为一条来接收
string[] asCommand = strRecvMessage.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
if (asCommand.Length >= 2)
{
lock (m_objListLock)
{
for (int i = 0; i < asCommand.Length; i++)
{
if (asCommand[i].Contains("COMMAND"))
{
if (asCommand[i].Contains("ID0")) //HeartBeat
{
//m_strDevicesConntectedStatus = asCommand[i].Substring(asCommand[i].IndexOf("COMMAND") + 7);
continue;
}
m_listRecvMessage.Add(asCommand[i] + "\r\n");
LoggerSocketHelper.InfoLog(string.Format("从{0}接收数据成功:{1}{2}", m_socket.RemoteEndPoint.ToString(), Environment.NewLine, asCommand[i]));
}
}
}
}
else
{
//过滤心跳
string ackSrc = asCommand[0];
string ack = ackSrc.Replace("#!HxSEP!#", "");
JObject job = JObject.Parse(ack);
int iType = Convert.ToInt32(job["message_type"].ToString());
if (iType == 0)
{
//LoggerSocketHelper.InfoLog(string.Format("从{0}接收心跳成功:{1}{2}", m_socket.RemoteEndPoint.ToString(), Environment.NewLine, asCommand[0]));
}
else if (iType == 4 || iType == 5)
{
string methodName = job["method"].ToString();
if (methodName != "ClawOpen")
{
m_listRecvMessage.Add(asCommand[0] + "\r\n");
m_countOfOnce++;
//LoggerSocketHelper.InfoLog(string.Format("从{0}接收数据成功:{1}{2}", m_socket.RemoteEndPoint.ToString(), Environment.NewLine, asCommand[0]));
}
}
}
}
}
///
/// 接收消息线程
///
private void RecvThreadMethod()
{
try
{
byte[] data = new byte[1024];
while (true)
{
/* * 0表示从数组的哪个索引开始读取数据 * 1024 表示最大的读取数 * */
try
{
// 接收服务器响应数据
byte[] buffer = new byte[81920];
int bytesRec = 0;
if (m_socket == null)
{
LoggerSocketHelper.DebugLog("[HxSocketClient][RecvThreadMethod]:Release:");
break;
}
if (m_socket.Connected)
{
bytesRec = m_socket.Receive(buffer);
}
if (bytesRec == 0)
{
// 服务断了
return;
}
string strRecvMessage = Encoding.ASCII.GetString(buffer, 0, bytesRec);
AddMessageToList(strRecvMessage);
}
catch (System.Exception ex)
{
LoggerSocketHelper.ErrorLog("[HxSocketClient][RecvThreadMethod]:ERROR:", ex);
}
}
}
catch (System.Exception ex)
{
LoggerSocketHelper.ErrorLog("[HxSocketClient][RecvThreadMethod]:ERROR:", ex);
}
}
///
/// 线程开始,启动函数
///
public void StartRecvThread()
{
try
{
recvThread = new Thread(new ThreadStart(RecvThreadMethod));
recvThread.Start();
LoggerSocketHelper.InfoLog(string.Format("[HxSocketClient][StartRecvThread]:打开RecvThread成功!ip:{0},port:{1}", m_ip, m_port));
}
catch (Exception ex)
{
LoggerSocketHelper.ErrorLog("ERROR:", ex);
}
}
///
/// 关闭接受数据线程
///
private void CloceRecvThread()
{
try
{
if (recvThread != null)
{
recvThread.Abort();
}
}
catch (Exception ex)
{
}
}
///
/// 获取通讯连接状态
///
///
public bool IsConnect()
{
try
{
if (m_socket == null)
{
return false;
}
else
{
return !((m_socket.Poll(1000, SelectMode.SelectRead) && (m_socket.Available == 0)) ||
!m_socket.Connected);
}
}
catch (Exception ex)
{
return false;
}
}
///
/// 检查数据
///
///
///
public string CheckData(List listRetData)
{
string rtnData = string.Empty;
if (listRetData.Count == 2)
{
// 检查Data是否报错
string strFinish = listRetData[1];
string finishData = strFinish.Replace("#!HxSEP!#", "");
HxResponseBase rtData = JsonConvert.DeserializeObject(finishData);
if (rtData.method_status == 3) // Failed
{
LoggerSocketHelper.DebugLog(string.Format("[CheckData]: method_status == 3, Response: {0}", listRetData[1]));
}
else if (rtData.message_type == 5 && rtData.method_status == 2) // Finish ComPleted
{
return finishData;
}
}
return rtnData;
}
}
}