using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Windows.Forms; using PluginCommon; using System.Diagnostics; namespace NetworkCommon.Network { public delegate void ConnectionChangeHandler(ConnectTools _gateway); public class ConnectTools: IDisposable { public static readonly string LOCALHOST = "127.0.0.1"; // const private string PluginName = "Unspecified_Plugin"; private const string PluginCmd = "PluginId"; private const int ThreadSleepTimeMs = 1; private const int UpdateConnectionPeriodMs = 100; // data readonly Thread m_thread = null; private pluginWrapper m_plugin = null; private engineWrapper m_engineWrapper = null; private EngineSettings m_engineSettings = null; private string m_connectIPOld; private int m_connectPortOld; private bool m_exitThread; public delegate void useCommand(ref blobWrapper blob); private readonly Dictionary m_hashCommand = new Dictionary(); #region Connection and properties /************************************************************************/ /* Instance */ /************************************************************************/ public static ConnectTools Instance { get; private set; } static ConnectTools() { Instance = new ConnectTools(); } /************************************************************************/ /* Event */ /************************************************************************/ public event ConnectionChangeHandler ConnectionStatusChanged; /************************************************************************/ /* Property */ /************************************************************************/ public string ConnectIP { get; set; } public int ConnectPort { get; set; } public bool Connected { get; private set; } public string DataRoot { get; private set; } public EngineSettings EngineSettings { get { return m_engineSettings; } set { m_engineSettings = value; if(ConnectPort == -1) { ConnectPort = m_engineSettings.Port; } } } /************************************************************************/ /* Constructor */ /************************************************************************/ private ConnectTools() { m_engineWrapper = new engineWrapper(""); ConnectIP = LOCALHOST; ConnectPort = -1; Connected = false; m_thread = new Thread(new ThreadStart(this.ThreadTask)); m_thread.IsBackground = true; } public void StartReceiveData(string _pluginName) { PluginName = _pluginName; m_exitThread = false; if(!m_thread.IsAlive) m_thread.Start(); } public void StopReceiveData() { if(m_thread.IsAlive) { m_exitThread = true; m_thread.Join(1000); } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public void Dispose(bool _disposing) { if(m_engineWrapper != null) { StopReceiveData(); m_engineWrapper.disconnect(); m_engineWrapper.destroy(); m_engineWrapper = null; } } ~ConnectTools() { Dispose(false); } #endregion #region ThreadTask /************************************************************************/ /* Message receive */ /************************************************************************/ /// /// Network thread /// private void ThreadTask() { OnConnectionChanged(); int count = 0; while(!m_exitThread) { if(count-- == 0) { count = UpdateConnectionPeriodMs / ThreadSleepTimeMs; updateConnectedStatus(); } //Receive messages if(Connected) receiveMessage(); Thread.Sleep(ThreadSleepTimeMs); } } public void disconnect() { m_engineWrapper.disconnect(); m_plugin = null; Connected = false; } private void SendConnected() { blobWrapper blob = new blobWrapper(); blob.push(PluginCmd); blob.push(PluginName); blob.sendToHost(); blob.Dispose(); } protected void OnConnectionChanged() { if(ConnectionStatusChanged != null) ConnectionStatusChanged(this); } /// /// Handle connection status /// public void updateConnectedStatus() { bool wasConnected = Connected; bool connected = Connected; bool connectionChanged = false; bool paramOK = (m_connectIPOld == ConnectIP) && (m_connectPortOld == ConnectPort); if(connected) { blobWrapper blob = new blobWrapper(); connected = blob.sendToHost(); blob.Dispose(); blob = null; } if(!connected || !paramOK) { if(wasConnected) { m_engineWrapper.disconnect(); m_plugin = null; connectionChanged = true; } // try to (re) connect connected = m_engineWrapper.connectToHost(ConnectIP, ConnectPort); if(connected) { m_connectIPOld = ConnectIP; m_connectPortOld = ConnectPort; connectionChanged = true; m_plugin = new pluginWrapper(); m_engineWrapper.addPlugin(PluginName, m_plugin); SendConnected(); } } if(connectionChanged) { Connected = connected; OnConnectionChanged(); } } #endregion #region message and commands private void execute(string command, ref blobWrapper blob) { useCommand func ; if (m_hashCommand.TryGetValue(command, out func)) { func(ref blob); } blob.Dispose(); } /************************************************************************/ /* Messages */ /************************************************************************/ private void receiveMessage() { if(m_plugin != null && m_engineWrapper.isConnected()) { m_engineWrapper.update(); blobWrapper blob = new blobWrapper(); while(m_plugin.dispatch(blob) && m_engineWrapper.isConnected()) { string command = ""; blob.extract(ref command); if(command == "dataroot") { string dataRoot = ""; blob.extractDataRoot(ref dataRoot); DataRoot = dataRoot; } else execute(command, ref blob); if(blob != null) blob.Dispose(); } if(blob != null) { blob.Dispose(); blob = null; } } } public void registerCommand(string name, useCommand fct) { m_hashCommand[name] = fct; } #endregion #region techno launching public static void StartWin32Techno(string _filename, string[] _args) { var process = new Process(); process.StartInfo.FileName = _filename; process.StartInfo.Arguments = $"\"{string.Join(";", _args)}\""; process.StartInfo.UseShellExecute = false; process.Start(); } #endregion } }