using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using SystemX.Common; using SystemX.Common.Serialization; using SystemX.Net.BaseProtocol; using SystemX.Net.Comm; using SystemX.Net.XAdaptor; using SystemX.Net.XAdaptor.PC.O2Sensor.NgCode; using SystemX.Net.Schedule; using static SystemX.Net.Platform.Common.Util.LogMessage; using WTimer = System.Windows.Forms.Timer; using System.IO.Compression; using SystemX.Net.Comm.IIS_FTP; namespace SystemX.Net.XAdaptor.PC { public partial class XAdaptorPC : XAdaptorSystem, IXPCAdaptor, IUIM, IComXPCAdaptor, IDisposable { private IPEndPoint ClientCommandEP; private IPEndPoint ClientStreamEP; private const int DISP_CONNECT_TIME_OUT = 5000; private const int CONNECT_TIME_OUT = 10000; private const int COMMAND_TIME_OUT = 20000; private const int FILE_SCAN_TIME = 250; private const int DEVICE_SCAN_TIME = 250; private const int RETRY_TIME = 5000; private const int LOGIN_TIMEOUT = 90000; private const int OBJECT_ACCESS_WAITTIME = 5000; private const int FILE_ACCESS_WAITTIME = 100; private const int OBJECT_ACCESS_CHECKTIME = 250; //1분 파일 전송 간격 private const int FILE_SEND_INTERVAL_TIME = 10000; //TODO : For Debug Test //5분 이상 파일전송이 없을경우 private const int FILE_SEND_MAX_WAITTIME = 300000; // 300000; private const int COMM_RETRY = 3; //private const double SESSION_TIMEOUT_SECOND = 300.0; #if FALSE private AsyncComClientSocket ClientCommandSock; private AsyncComClientSocket ClientStreamSock; #else private AsyncClientSocket ClientCommandSock; private AsyncClientSocket ClientStreamSock; #endif private Task taskRecvCommandProcess; private bool m_bTaskCommandBlock; private Task taskRecvStreamProcess; private bool m_bTaskStreamBlock; private Task taskSubProcess; private bool m_bTaskSubBlock; // private CancellationTokenSource CommandCTS; private CancellationToken CommandCT; private CancellationTokenSource StreamCTS; private CancellationToken StreamCT; private CancellationTokenSource SubCTS; private CancellationToken SubCT; // private bool bConnectCommandSocketFlag; private bool bConnectStreamSocketFlag; // private PacketFlowControl FlowCommandControl; private PacketFlowControl FlowStreamControl; private event RecvWaitEventHandler RecvWaitEvent; private WaitParameter waitCommandParam; private WaitParameter waitStreamParam; internal class QueryDataSetResult { public XData xData; public bool bQueryResult; public DataSet QueryDataSet; public string strVarParam1; public string strVarParam2; public string strVarParam3; public bool bFileRecvResult; public bool bFileProcessResult; public void Initialize() { xData = null; bQueryResult = false; QueryDataSet = null; strVarParam1 = string.Empty; strVarParam2 = string.Empty; strVarParam3 = string.Empty; bFileRecvResult = false; bFileProcessResult = false; } } private QueryDataSetResult QueryResult = new QueryDataSetResult(); //Command Socket Retry Time private Stopwatch streCommandConnectWatch; //Stream Socket Retry Time private Stopwatch streStreamConnectWatch; //File Send & File Backup Time private Stopwatch stFileSendTime; private Stopwatch stBackupFileSendTime; private Task tkReCommandConnect; private Task tkReStreamConnect; private WTimer reConnectTimer; // private bool[] START_EVENT_TRIGGER; private string strSetAdaptorConfigFilePos; private string strCheckCommandMsg; private string strCheckStreamMsg; private static SemaphoreSlim _smpSlim = new SemaphoreSlim(1, 1); private static bool bTaskSubLockState = false; //private static readonly object objFileSendLock = new object(); private static bool bTaskCommandWaitLock = false; private static bool bTaskStreamWaitLock = false; private bool bReqConnectFailed; private int nReqConnectNum; // private NGCodeMgr dbNgCodeFinder; public NGCodeMgr GetNgCodeMgr() { if (dbNgCodeFinder != null) return dbNgCodeFinder; else return null; } private enum TIMER_LOCK { RECONNECT_TIMER = 0 } private bool[] m_bTimerLock; private void InitMember() { GetMiddlewareMessage = "OFF"; CommandCTS = new CancellationTokenSource(); CommandCT = CommandCTS.Token; StreamCTS = new CancellationTokenSource(); StreamCT = StreamCTS.Token; SubCTS = new CancellationTokenSource(); SubCT = SubCTS.Token; // streCommandConnectWatch = new Stopwatch(); streCommandConnectWatch.Start(); streStreamConnectWatch = new Stopwatch(); streStreamConnectWatch.Start(); stFileSendTime = new Stopwatch(); stFileSendTime.Start(); stBackupFileSendTime = new Stopwatch(); stBackupFileSendTime.Start(); // tkReCommandConnect = null; tkReStreamConnect = null; strSetAdaptorConfigFilePos = string.Empty; AdaptorInformation = new ClientConnInfo(); // bConnectCommandSocketFlag = false; bConnectStreamSocketFlag = false; } public XAdaptorPC() { InitMember(); /* For LeakTest */ if (COMMON.FIX_INFO_MODE) { IPEndPoint CommandEp = null; IPEndPoint StreamEp = null; CommandEp = new IPEndPoint(IPAddress.Parse("200.200.200.48"), 5124); StreamEp = new IPEndPoint(IPAddress.Parse("200.200.200.48"), 7124); //TempCode //CommandEp = new IPEndPoint(IPAddress.Loopback, 5124); //StreamEp = new IPEndPoint(IPAddress.Loopback, 7124); Initialize(CommandEp, StreamEp); } else { //For Normal Process Initialize(); } } public XAdaptorPC(IPEndPoint SetCommandEp = null, IPEndPoint SetStreamEp = null) { InitMember(); Initialize(SetCommandEp, SetStreamEp); } ~XAdaptorPC() { Dispose(false); } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool bDisposing) { RecvWaitEvent -= RecvWaitEventCall; if (bDisposing) { ClearCommandWatchTask(); ClearStreamWatchTask(); } ClearCommandClientInstance(); ClearStreamClientInstance(); // do releasing unmanaged resource (종결자가 없는 객체의 자원 해제) // i.e. close file handle of operating systems // suppress calling of Finalizer GC.SuppressFinalize(this); } private void SetRetryTimer() { reConnectTimer = new WTimer(); reConnectTimer.Enabled = false; reConnectTimer.Interval = 1500; reConnectTimer.Tick += ReConnectTimer_Tick; reConnectTimer.Start(); reConnectTimer.Enabled = true; } private bool CheckConfigFileBuildEndPoint() { bool bCheckResult = true; var sFilePath = ""; if (strSetAdaptorConfigFilePos.Length <= 0) sFilePath = Directory.GetCurrentDirectory() + @"\Configure\" + "ClientInformation.xml"; else sFilePath = strSetAdaptorConfigFilePos; if (File.Exists(sFilePath) == false) { MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"SystemX.Net.XAdaptor.PC Configuration file does not exist. " + "[SystemX.Net.XAdaptor.PC : XPCAdaptor.CheckConfigFileBuildEndPoint]", ConsoleColor.Yellow, LogMessageLevel.FATAL); bCheckResult = false; } else { LoadInfo = new ClientInfo(sFilePath); if (LoadInfo.Load() == false) { bCheckResult = false; MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"SystemX.Net.XAdaptor.PC Configuration file loading Error. " + "[SystemX.Net.XAdaptor.PC : XPCAdaptor.CheckConfigFileBuildEndPoint]", ConsoleColor.Yellow, LogMessageLevel.FATAL); } else { AdaptorInformation.CONNECT_IP = LoadInfo.CONNECT_IP; AdaptorInformation.SECTION = LoadInfo.SECTION; AdaptorInformation.HOST_ID = LoadInfo.HOST_ID; AdaptorInformation.TEST_CODE = LoadInfo.TEST_CODE; AdaptorInformation.COMMAND_PORT = LoadInfo.COMMAND_PORT; AdaptorInformation.STREAM_PORT = LoadInfo.STREAM_PORT; AdaptorInformation.LOGIN_RESULT = false; AdaptorInformation.LOGIN_MESSAGE = string.Empty; } } StateAdaptorConnect = bCheckResult; if (ClientReadyEndPoint && bCheckResult) SetEpCommandStream(); return bCheckResult; } private void SetDefaultConfig() { LoadInfo = new ClientInfo(); LoadInfo.LOOP_BACK = false; LoadInfo.CONNECT_IP = ClientCommandEP.Address.ToString(); LoadInfo.COMMAND_PORT = ClientCommandEP.Port; LoadInfo.STREAM_PORT = ClientStreamEP.Port; LoadInfo.READ_INFO_STATE = true; StateAdaptorConnect = true; } private void SetEpCommandStream() { if (LoadInfo.LOOP_BACK) { ClientCommandEP = new IPEndPoint(IPAddress.Loopback, LoadInfo.COMMAND_PORT); ClientStreamEP = new IPEndPoint(IPAddress.Loopback, LoadInfo.STREAM_PORT); } else { ClientCommandEP = new IPEndPoint(IPAddress.Parse(LoadInfo.CONNECT_IP), LoadInfo.COMMAND_PORT); ClientStreamEP = new IPEndPoint(IPAddress.Parse(LoadInfo.CONNECT_IP), LoadInfo.STREAM_PORT); } } private void AdaptorAbort(bool bForceClear = false) { ClearCommonVar(); ClearCommandWatchTask(); ClearStreamWatchTask(); if (bForceClear == true) { try { XAdaptorLogWrite("AdaptorAbort - Command Socket Disconnect"); XAdaptorLogWrite("AdaptorAbort - Stream Socket Disconnect"); streCommandConnectWatch.Restart(); streStreamConnectWatch.Restart(); thisConnInfo.ConnectCommandState = false; thisConnInfo.ConnectStreamState = false; SubscribeConnectInfo.Initialize(); StateClientSocketConnect = false; StateClientGetInformation = false; StateClientStreamSocketConnect = false; } catch (Exception ex) { MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"Abort socket all-clear information error. [SystemX.Net.XAdaptor.PC : XPCAdaptor.AdaptorAbort]\r\n" + ex.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG); } } OnCommandDisconnectAlarm(null, null); OnStreamDisconnectAlarm(null, null); ClearCommandClientInstance(); ClearStreamClientInstance(); } private async void ReConnectTimer_Tick(object sender, EventArgs e) { if (m_bTimerLock[(int)TIMER_LOCK.RECONNECT_TIMER] == false) { m_bTimerLock[(int)TIMER_LOCK.RECONNECT_TIMER] = true; if(SubscribeConnectInfo.bSetChangeConnect) { if (SubscribeConnectInfo.bReqConnectAbort == false) SubscribeConnectInfo.bReqConnectAbort = true; else { if (bReqConnectFailed) { bReqConnectFailed = false; if (nReqConnectNum < 2) { SubscribeConnectInfo.bSetChangeConnect = false; await ComClientTryDistributionConnet(); } else SubscribeConnectInfo.bSetChangeConnect = false; } else { if (ConnectStartStyleAuto == false) SubscribeConnectInfo.bSetChangeConnect = false; else { if (await ComClientTryConnet(SubscribeConnectInfo.nChangeCommandPort, SubscribeConnectInfo.nChangeStreamPort)) SubscribeConnectInfo.bSetChangeConnect = false; else { AdaptorAbort(); bReqConnectFailed = true; nReqConnectNum++; SubscribeConnectInfo.bReqConnectAbort = false; } } } } } if (SubscribeConnectInfo.bUIMUseMode && SubscribeConnectInfo.bSessionStarted) { if (LoadInfo.SESSION_TIMEOUT_TIME_S > 0.0) { if (SubscribeConnectInfo.GetSessionTime().TotalSeconds >= LoadInfo.SESSION_TIMEOUT_TIME_S) { AdaptorAbort(); } } } // /* if (START_EVENT_TRIGGER[0]) { START_EVENT_TRIGGER[0] = false; //CommandConnectAlarmEvent?.BeginInvoke(null, null, null, null); //CommandConnectAlarmEvent?.Invoke(null, null); OnCommandConnectAlarm(null, null); } if (START_EVENT_TRIGGER[1]) { START_EVENT_TRIGGER[1] = false; //StreamConnectAlarmEvent?.BeginInvoke(null, null, null, null); //StreamConnectAlarmEvent?.Invoke(null, null); OnStreamConnectAlarm(null, null); } */ // /* //Command Stream Conn Check if (StateClientSocketConnect == false) goto ROUTINE_OUT; if (thisConnInfo.stCommandCheckTime.ElapsedMilliseconds >= 60000) { SendCommandConnectState(); thisConnInfo.OnCommandCheckTime(); } // if (StateClientStreamSocketConnect == false) goto ROUTINE_OUT; if (thisConnInfo.stStreamCheckTime.ElapsedMilliseconds >= 60000) { SendStreamConnectState(); thisConnInfo.OnStreamCheckTime(); } ROUTINE_OUT: */ m_bTimerLock[(int)TIMER_LOCK.RECONNECT_TIMER] = false; } } private void Initialize(IPEndPoint SetCommandEp = null, IPEndPoint SetStreamEp = null) { waitCommandParam = new WaitParameter(); waitStreamParam = new WaitParameter(); mgrPRODTestList = CreateTestListMgr(); bReqConnectFailed = false; nReqConnectNum = 0; //Ng code decoder dbNgCodeFinder = null; ClientReadyEndPoint = false; if (SetCommandEp != null && SetStreamEp != null) { ClientCommandEP = SetCommandEp; ClientStreamEP = SetStreamEp; ClientReadyEndPoint = true; } MessageOutput.PrintLogLevel = LogMessageLevel.INFO; StateAdaptorConnect = true; // StateClientSocketConnect = false; StateClientStreamSocketConnect = false; // StateClientGetInformation = false; // ClientCommandSock = null; ClientStreamSock = null; FlowCommandControl = null; FlowStreamControl = null; RecvWaitEvent += RecvWaitEventCall; thisConnInfo = new ClientInfoStore(); // m_bTimerLock = new bool[10]; Array.Clear(m_bTimerLock, 0, 10); // if (ClientReadyEndPoint == false) CheckConfigFileBuildEndPoint(); else SetDefaultConfig(); // if (StateAdaptorConnect) { ;// } // thisConnInfo.OnCommandTime(); thisConnInfo.OnCommandCheckTime(); thisConnInfo.OnStreamTime(); thisConnInfo.OnStreamCheckTime(); // //if (CLIENT_AUTO_CONNECT) SetRetryTimer(); } // TODO : FTP ALIS internal eFTPServiceStatus StartFTPService() { if (LoadInfo.FTP_Use) { ControlFTP = new CtrlFTP(LoadInfo.FTP_Use, IPAddress.Parse(LoadInfo.FTP_IPAddress), Convert.ToInt32(LoadInfo.FTP_Port), LoadInfo.FTP_Account, LoadInfo.FTP_Password); if (ControlFTP.FTPConnState) return eFTPServiceStatus.Connected; else return eFTPServiceStatus.Disconnected; } else return eFTPServiceStatus.Unused; } public DataSet WaitSystemQuery(string strQuery) { if (thisConnInfo.ConnectCommandState == false) return null; if (thisConnInfo.InitialInfoState == false) return null; if (LoadInfo.SIMPLE_LOOKUP_OPTION == true) return null; DataSet dsReturnSet = null; try { thisConnInfo.OnCommandTime(); try { QUERY_PACKET QueryPacket = new QUERY_PACKET(); int iSizeQueryPacket = Marshal.SizeOf(QueryPacket); byte[] ucQueryPacketArray = new byte[iSizeQueryPacket]; QueryPacket = (QUERY_PACKET)SystemXNetSerialization.RawDeSerialize(ucQueryPacketArray, QueryPacket.GetType()); QueryPacket.objQueryText[0].Data = strQuery; ucQueryPacketArray = XCommons.SpecialObjectToByteStream(new BASE_PROTOCOL(BASE_PROTOCOL.PROTOCOL_CODE.SYSTEM_QUERY), QueryPacket); byte ucGetLabel = FlowCommandControl.InsertSendQueue(DateTime.Now, ucQueryPacketArray, null, true); WaitThreadJoin(waitCommandParam, FlowCommandControl, ucGetLabel); if (QueryResult.QueryDataSet != null) { if (QueryResult.bQueryResult) //Query 문 실행 성공 dsReturnSet = QueryResult.QueryDataSet; else //Query 문 실행 실패(구문 오류 또는 연결 오류) dsReturnSet = null; } } catch (Exception ex) { MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"Internal use program query failure. [" + strQuery + "][SystemX.Net.XAdaptor.PC - IXPCAdaptor : XPCAdaptor.WaitSystemQuery]\r\n" + ex.Message, ConsoleColor.Yellow, LogMessageLevel.FATAL); } finally { } } finally { ; } return dsReturnSet; } } }