using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Project.Device { public class Socket { public enum eType { REQUEST, REPLY, } public enum eSType { STATUS, GEN, SPL } public struct Message { public Boolean isError; public string ErrorMessage; public string Asset; public eType Type; public eSType SType; public string Body; public string timeStamp; } private Winsock_Orcas.Winsock wsListen; private Winsock_Orcas.Winsock wsData; private char sepMsg = (char)0x07; private char sepBody = (char)0x09; public int ListenPort { get; set; } public string errorMessage { get; set; } public event EventHandler RecvMessage; public event EventHandler SendMessage; public event EventHandler GetMessage; private void RaiseMessage(string msg, Boolean isErr = false) { if (GetMessage != null) GetMessage(this, new MesasgeEventArgs(msg, isErr)); } private void RaiseSendMessage(Message msg, string raw) { if (SendMessage != null) { try { SendMessage(this, new SocketMessageEventArgs(msg, raw)); } catch (Exception ex) { this.errorMessage = ex.Message; } } } private void RaiseRecvMessage(Message msg, string raw) { if (RecvMessage != null) { try { RecvMessage(this, new SocketMessageEventArgs(msg, raw)); } catch (Exception ex) { this.errorMessage = ex.Message; } } } public Socket() { wsListen = new Winsock_Orcas.Winsock(); wsData = new Winsock_Orcas.Winsock(); wsListen.LegacySupport = true; wsData.LegacySupport = true; wsData.Connected += wsData_Connected; wsData.Disconnected += wsData_Disconnected; wsData.DataArrival += wsData_DataArrival; wsData.ErrorReceived += wsData_ErrorReceived; wsListen.ConnectionRequest += wsListen_ConnectionRequest; wsListen.ErrorReceived += wsListen_ErrorReceived; } void wsListen_ErrorReceived(object sender, Winsock_Orcas.WinsockErrorReceivedEventArgs e) { RaiseMessage("LTERR:" + e.Details, true); } void wsData_ErrorReceived(object sender, Winsock_Orcas.WinsockErrorReceivedEventArgs e) { RaiseMessage("RXERR:"+e.Details, true); } void wsData_Disconnected(object sender, EventArgs e) { RaiseMessage("Disconnected"); } void wsData_Connected(object sender, Winsock_Orcas.WinsockConnectedEventArgs e) { RaiseMessage("Conncted"); } void wsListen_ConnectionRequest(object sender, Winsock_Orcas.WinsockConnectionRequestEventArgs e) { if (wsData.State != Winsock_Orcas.WinsockStates.Closed) { wsData.Close(); System.Threading.Thread.Sleep(500); } RaiseMessage("Connection Request " + e.ClientIP); try { wsData.Accept(e.Client); }catch (Exception ex) { RaiseMessage("Connection Request\n"+ex.Message, true); } } ~Socket() { if (wsData != null) { wsData.DataArrival -= wsData_DataArrival; wsData.Connected += wsData_Connected; wsData.Disconnected += wsData_Disconnected; } if (wsListen != null) { wsListen.ConnectionRequest += wsListen_ConnectionRequest; } if (wsListen != null && wsListen.State != Winsock_Orcas.WinsockStates.Closed) wsListen.Close(); if (wsData != null && wsData.State != Winsock_Orcas.WinsockStates.Closed) wsData.Close(); wsData.Dispose(); wsListen.Dispose(); } public Boolean Listen(int port) { try { ListenPort = port; wsListen.Listen(this.ListenPort); this.errorMessage = string.Empty; return true; } catch (Exception ex) { this.errorMessage = ex.Message; return false; } } public Boolean isListen { get { return wsListen.State == Winsock_Orcas.WinsockStates.Listening; } } public Boolean isConn { get { return wsData.State == Winsock_Orcas.WinsockStates.Connected; } } public Message LastSendMessage = new Message(); private Message makeMessage(string Asset, eType type, eSType subtype, string body) { Message retval = new Message(); retval.Asset = Asset; retval.Type = type; retval.SType = subtype; retval.Body = body; retval.isError = true; retval.ErrorMessage = string.Empty; retval.timeStamp = DateTime.Now.ToString("yyyyMMddHHmmss"); return retval; } /// /// Body문자열을 구분자를 기준으로 한 배열로 반환 함 /// /// /// public string[] getBodyArray(string bodyMessage) { return bodyMessage.Split(sepBody); } /// /// 패킷의 내용을 메세지로 분리한다. /// /// /// private Message ParseMessage(string PacketMessage) { Message retval = new Message(); retval.isError = false; retval.ErrorMessage = string.Empty; var buffer = PacketMessage.Split(sepMsg); if (buffer.Length != 5) { retval.isError = true; retval.ErrorMessage = "Packet Size Error : Expect 5 Array"; return retval; } else { retval.Asset = buffer[0]; if (!getType(buffer[1], out retval.Type)) { retval.isError = true; retval.ErrorMessage = "지정된 Type 이 아닙니다(" + buffer[1] + ")"; return retval; } if (!getSType(buffer[2], out retval.SType)) { retval.isError = true; retval.ErrorMessage = "지정된 SubType 이 아닙니다(" + buffer[2] + ")"; return retval; } retval.timeStamp = buffer[3]; //DateTime timeStamp; //if (!DateTime.TryParse(retval.timeStamp, out timeStamp)) //{ // retval.isError = true; // retval.ErrorMessage = "timeStamp 해석 오류(" + retval.timeStamp + ")"; // return retval; //} retval.Body = buffer[4]; } return retval; } private Boolean getType(string strType, out eType type) { type = eType.REPLY; var list = Enum.GetNames(typeof(eType)); int value = -1; for (int i = 0; i < list.Length; i++) { if (list[i].ToUpper() == strType.ToUpper()) { value = i; break; } } if (value == -1) return false; type = (eType)value; return true; } private Boolean getSType(string strSType, out eSType stype) { stype = eSType.GEN; var list = Enum.GetNames(typeof(eSType)); int value = -1; for (int i = 0; i < list.Length; i++) { if (list[i].ToUpper() == strSType.ToUpper()) { value = i; break; } } if (value == -1) return false; stype = (eSType)value; return true; } public string makePacket(Message msg) { //프레임구조 asset chr(7) + type + chr(7) + stype + char(7) + timeStamp + char(7) + body" //timestamp = yyyymmddhhmmss //sepChar = (char)0x07; System.Text.StringBuilder buffer = new StringBuilder(); buffer.Append(msg.Asset); buffer.Append(sepMsg); buffer.Append(msg.Type.ToString()); buffer.Append(sepMsg); buffer.Append(msg.SType.ToString()); buffer.Append(sepMsg); buffer.Append(msg.timeStamp); buffer.Append(sepMsg); buffer.Append(msg.Body); return buffer.ToString(); } public string makeLotSplitPacket( string fcst, string tcst, string slot, string wafer) { System.Text.StringBuilder buffer = new StringBuilder(); buffer.Append(fcst); buffer.Append(sepBody); buffer.Append(tcst); buffer.Append(sepBody); buffer.Append(slot); buffer.Append(sepBody); buffer.Append(wafer); return buffer.ToString(); } public string makeLotGenPacket(string Lot, string cst, string slot, string wafer) { System.Text.StringBuilder buffer = new StringBuilder(); buffer.Append(Lot); buffer.Append(sepBody); buffer.Append(cst); buffer.Append(sepBody); buffer.Append(slot); buffer.Append(sepBody); buffer.Append(wafer); return buffer.ToString(); } public enum eStatus { RUN =0, IDLE , ALARM, } public string makeReplyStatus(eStatus Status) { System.Text.StringBuilder buffer = new StringBuilder(); buffer.Append(((int)Status).ToString()); return buffer.ToString(); } public Boolean Send(string Asset, eType type, eSType subtype, string body) { var msg = makeMessage(Asset, type, subtype, body); var isStatus = subtype == eSType.STATUS; return Send(msg, isStatus); } public Boolean isReplyRecv = false; public Boolean Send(Message msg,Boolean isStatus) { var packet = makePacket(msg); if (wsData.State != Winsock_Orcas.WinsockStates.Connected) { errorMessage = "Not Connected"; return false; } try { if(isStatus==false) isReplyRecv = false; //190129 wsData.Send(packet + "\r\n"); errorMessage = string.Empty; LastSendMessage = msg; RaiseSendMessage(msg, packet); return true; } catch (Exception ex) { errorMessage = ex.Message; return false; } } public Message LastReplyMessage = new Message(); public Message LastRecvMessage = new Message(); void wsData_DataArrival(object sender, Winsock_Orcas.WinsockDataArrivalEventArgs e) { var sock = sender as Winsock_Orcas.Winsock; var data = sock.Get(); if(PUB.setting.LOg_SocketRecv) { if (data.IndexOf("REQUEST") != -1 && data.IndexOf("STATUS") != -1) { //핑 명령 } else PUB.log.AddE("Socket Recv : " + data); //190129 } LastRecvMessage = ParseMessage(data); if (LastRecvMessage.isError) PUB.log.AddE("Socket Message error" + LastRecvMessage.ErrorMessage); else { //190129 - reply만 별도 처리함 if (LastRecvMessage.Type == eType.REPLY) { LastReplyMessage = ParseMessage(data); isReplyRecv = true; } } RaiseRecvMessage(LastRecvMessage, data); } public class SocketMessageEventArgs : EventArgs { public string rawData { get; set; } public Device.Socket.Message Message { get; set; } public SocketMessageEventArgs(Device.Socket.Message msg, string raw) { this.Message = msg; this.rawData = raw; } } public class MesasgeEventArgs : EventArgs { public string Message { get; set; } public Boolean isError { get; set; } public MesasgeEventArgs(string msg, Boolean iserr) { this.Message = msg; this.isError = iserr; } } } }