#region Namespace using System; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Threading; using com.itac.mes.proxy.business; using com.itac.oib; using com.itac.mes.tools; #endregion namespace com.itac.mes.proxy.sockets { public class SocketAdapter { private readonly IList _channels = new List(); private readonly TcpListener _listener; private readonly IAdapterControl _adapterControl; private readonly OIBServiceImpl _serviceImpl; private bool _isShutdown = false; // Wenn ein IHapHandler ein Disconnect feststellt wird eine Verbindung entfernt... public void ClientDisconnected(IhapHandler iHapHandler) { // remove handler with disconnected sockets for (int i = _channels.Count - 1; i >= 0; i--) { IhapHandler element = _channels[i]; if (element == iHapHandler) { _channels[i].shutdown(); _channels.RemoveAt(i); LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Remove socket connection."); } } LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "Nr of active connections: " + _channels.Count); } public SocketAdapter(int listeningPort, IAdapterControl adapterControl, OIBServiceImpl serviceImpl) { _listener = new TcpListener(IPAddress.Any, listeningPort); _listener.Start(); LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Listen on port " + listeningPort); _adapterControl = adapterControl; _serviceImpl = serviceImpl; var thread = new Thread(Run); thread.Start(); LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Startup " + Constants.SERVICE_NAME + " finished."); // // neuen Thread aufmachen, der immer wieder nachguckt, wie oft die IHapHandler benutzt werden. und unbenutzte Verbindungen entfernt var checkAliveThread = new Thread(RunCheckAlive); checkAliveThread.Start(); } public void Run() { Thread.CurrentThread.Name = "SocketAdapter"; while (!_isShutdown) { TcpClient client; try { client = _listener.AcceptTcpClient(); } catch (SocketException se) { LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Accepting new socket connection failed", se); continue; } var handler = new IhapHandler(client, _serviceImpl); handler.setAdapterControl(_adapterControl); handler.ClientDisconnected += ClientDisconnected; _channels.Add(handler); LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Incoming socket connection from " + client.Client.RemoteEndPoint); } } public void RunCheckAlive() { Thread.CurrentThread.Name = "CheckAliveThread"; while (!_isShutdown) { bool removed = false; LogHandler.log(Constants.LOGGER, TraceEventType.Information, "registered incoming socket connections: " + _channels.Count); try { for (int i = _channels.Count - 1; i >= 0; i--) { var channel = _channels[i]; if (!channel.isConnected()) { LogHandler.log(Constants.LOGGER, TraceEventType.Information, "remove disconnected incoming socket connection for " + channel.getName()); _channels.Remove(channel); removed = true; continue; } LogHandler.log(Constants.LOGGER, TraceEventType.Information, "" + channel.getName() + " channel last used: " + new DateTime(channel.getLastCall())); if ((channel.getLastCall() + 36001000L) < DateTime.Now.Ticks) // eine Stunde... { // Verbindung schliessen, wenn Sie länger als ... nicht benutzt wurde // channel.shutdown(); } } if (removed) { LogHandler.log(Constants.LOGGER, TraceEventType.Information, "remaining open incoming socket connections after cleanup: " + _channels.Count); } } catch (Exception ) { LogHandler.log(Constants.LOGGER, TraceEventType.Information, "service channel listing interrupted"); } // LG: Why this?? Thread.Sleep(60000); } } public void Shutdown() { _isShutdown = true; try { _listener.Stop(); foreach (var channel in _channels) { if (channel.isConnected()) { channel.shutdown(); } } _channels.Clear(); } catch { } LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Listen port closed."); } } }