Files
imsInterface/interface/commonsmt/dotnetplugin/Plugin/SocketAdapter.cs
2025-06-06 09:15:13 +02:00

155 lines
5.6 KiB
C#

#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;
#endregion
namespace com.itac.mes.proxy.sockets
{
public class SocketAdapter
{
private readonly IList<IhapHandler> _channels = new List<IhapHandler>();
private readonly TcpListener _listener;
private readonly IAdapterControl _adapterControl;
private readonly OIBServiceImpl _serviceImpl;
private bool _isShutdown = false;
private int listeningPort;
// 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.");
}
}
}