155 lines
5.6 KiB
C#
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.");
|
|
}
|
|
}
|
|
}
|