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; } } }