initialize
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Runtime.Remoting.Proxies;
|
||||
using System.Threading;
|
||||
using com.itac.artes.ihap;
|
||||
using com.itac.mes.domain;
|
||||
using com.itac.mes.tools;
|
||||
using com.itac.oib;
|
||||
using com.itac.oib.boardgatekeeper.service;
|
||||
using com.itac.oib.linecontrol.service;
|
||||
using com.itac.oib.monitoring.service;
|
||||
using com.itac.oib.siplacesetupcenter.service;
|
||||
using com.itac.oib.traceability.service;
|
||||
|
||||
|
||||
// Handler der das callen von Methoden des DataInterface aus dem iTAC.OIB.Adapter übernimmt
|
||||
namespace com.itac.mes.proxy.sockets
|
||||
{
|
||||
|
||||
public delegate void PropertyChangeListener(object sender, string channelName, string message);
|
||||
|
||||
|
||||
public class IhapEventChannel : RealProxy
|
||||
{
|
||||
|
||||
private static int CONNECTION_CHECK_MILLIES = 500;
|
||||
|
||||
private TcpClient _client;
|
||||
private IhapOutputStream _ios;
|
||||
private IhapInputStream _iis;
|
||||
private bool _isShutdown;
|
||||
public string channelName { get; set; }
|
||||
private long lastCall = DateTime.Now.Ticks;
|
||||
private Object lockObject = new Object();
|
||||
private Thread aliveThread;
|
||||
|
||||
public event PropertyChangeListener connectionStateChangeListener;
|
||||
|
||||
public IhapEventChannel(TcpClient client, String channelName)
|
||||
: base(typeof(OIBEvents))
|
||||
{
|
||||
lock (typeof(IhapHandler))
|
||||
{
|
||||
}
|
||||
this.channelName = channelName;
|
||||
this._client = client;
|
||||
_ios = new IhapOutputStream(_client.GetStream());
|
||||
_iis = new IhapInputStream(_client.GetStream());
|
||||
|
||||
aliveThread = new Thread(new ThreadStart(aliveThreadRun));
|
||||
}
|
||||
|
||||
public void shutdown()
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "closing channel" + channelName);
|
||||
_isShutdown = true;
|
||||
try
|
||||
{
|
||||
_client.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "closing channel" + channelName + " failed");
|
||||
}
|
||||
}
|
||||
|
||||
public long getLastCall()
|
||||
{
|
||||
return lastCall;
|
||||
}
|
||||
|
||||
public bool isConnected()
|
||||
{
|
||||
return _client.Client.Connected;
|
||||
}
|
||||
|
||||
public bool isShutdownInProgress()
|
||||
{
|
||||
return _isShutdown;
|
||||
}
|
||||
|
||||
public override IMessage Invoke(IMessage message)
|
||||
{
|
||||
lastCall = new DateTime().Ticks;
|
||||
IMethodCallMessage methodMsg = (IMethodCallMessage)message;
|
||||
try
|
||||
{
|
||||
MethodInfo methodInfo = typeof(OIBEvents).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
|
||||
Type[] interfaces = typeof(OIBEvents).GetInterfaces();
|
||||
foreach (Type t in interfaces)
|
||||
{
|
||||
methodInfo = t.GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
if (methodInfo != null)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("found method {0} in interface {1}", methodInfo.Name, t.Name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (methodInfo == null)
|
||||
{
|
||||
throw new Exception("IHapEventChannel: methode '" + methodMsg.MethodName + "' not found in any of the interfaces");
|
||||
}
|
||||
|
||||
object[] args = methodMsg.Args;
|
||||
if (methodMsg.MethodName.Equals("Equals"))
|
||||
{
|
||||
return new ReturnMessage(args[0].Equals(this), args, 0, methodMsg.LogicalCallContext, methodMsg);
|
||||
}
|
||||
else if (methodMsg.MethodName.Equals("GetHashCode"))
|
||||
{
|
||||
return new ReturnMessage(this.GetHashCode(), args, 0, methodMsg.LogicalCallContext, methodMsg);
|
||||
}
|
||||
else if (methodMsg.MethodName.Equals("shutdown"))
|
||||
{
|
||||
shutdown();
|
||||
stopAliveThread();
|
||||
connectionClosed();
|
||||
return new ReturnMessage(null, args, 0, methodMsg.LogicalCallContext, methodMsg);
|
||||
}
|
||||
else if (methodMsg.MethodName.Equals("startup"))
|
||||
{
|
||||
aliveThread.Start();
|
||||
return new ReturnMessage(null, args, 0, methodMsg.LogicalCallContext, methodMsg);
|
||||
}
|
||||
Object retValue = sendCall(methodInfo, args);
|
||||
return new ReturnMessage(retValue, args, 0, methodMsg.LogicalCallContext, methodMsg);
|
||||
}
|
||||
catch (TargetInvocationException ite)
|
||||
{
|
||||
return new ReturnMessage(ite.GetBaseException(), methodMsg);
|
||||
}
|
||||
catch (Exception ite)
|
||||
{
|
||||
return new ReturnMessage(ite.GetBaseException(), methodMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private Object sendCall(MethodInfo method, Object[] args)
|
||||
{
|
||||
lock (lockObject)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "Send event '" + method.Name + "' to socket " + _client.Client.RemoteEndPoint + " on " + channelName);
|
||||
Object result = null;
|
||||
try
|
||||
{
|
||||
_ios.writeBoolean(false);
|
||||
_ios.call(method, args);
|
||||
_ios.Flush();
|
||||
IhapReply reply = _iis.readReply();
|
||||
if (reply is IhapSuccessReply)
|
||||
{
|
||||
result = ((IhapSuccessReply)reply).getReturnValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
IhapFaultReply fault = (IhapFaultReply)reply;
|
||||
switch (fault.getFaultCode())
|
||||
{
|
||||
case FaultCode.NoSuchMethodException:
|
||||
throw new NotImplementedException(fault.getMessage());
|
||||
case FaultCode.ProtocolException:
|
||||
throw new IhapProtocolException(fault.getMessage(), null);
|
||||
default:
|
||||
throw new IhapProtocolException(fault.getMessage(), null);
|
||||
//(Exception)fault.getException();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "Error while sending event call on " + channelName + ":" + e.Message + "\n" + e.StackTrace);
|
||||
shutdown();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void connectionClosed()
|
||||
{
|
||||
// Hier wird überprüft, ob ein Eintrag in der Aufruf-Liste vorhanden ist.
|
||||
if (this.connectionStateChangeListener != null)
|
||||
{
|
||||
// Hier wird jeder Delegat, der sich für den Event registriert hat, aufgerufen.
|
||||
this.connectionStateChangeListener(this, channelName, "connectionClosed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void stopAliveThread()
|
||||
{
|
||||
if (aliveThread.IsAlive && (aliveThread.ThreadState != System.Threading.ThreadState.Running))
|
||||
{
|
||||
aliveThread.Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void aliveThreadRun()
|
||||
{
|
||||
while (!_isShutdown && aliveThread.ThreadState == System.Threading.ThreadState.Running)
|
||||
{
|
||||
// wenn der letzte Call länger als .. her ist...
|
||||
try
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// wenn beim schliessen der Verbindung noch was passiert ist das nicht schlimm
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "interrupted for " + channelName);
|
||||
}
|
||||
if (DateTime.Now.Ticks - lastCall > CONNECTION_CHECK_MILLIES)
|
||||
{
|
||||
try
|
||||
{
|
||||
// versuchen den Server zu pingen
|
||||
// wenn das fehlschlägt ist die Verbindung kaputt
|
||||
lock (lockObject)
|
||||
{ // das erfolgreiche Schreiben eines booleschen Wertes ist aus Kommunikationssicht zu sehen wie der
|
||||
// erfolgreiche Aufruf einer Methode
|
||||
if (!_isShutdown && (aliveThread.ThreadState == System.Threading.ThreadState.Running))
|
||||
{
|
||||
// nur wenn die Verbindung nicht bereits gestoppt wurde...
|
||||
_ios.writeBoolean(true);
|
||||
_ios.Flush();
|
||||
lastCall = DateTime.Now.Ticks;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
_isShutdown = true;
|
||||
_client.Close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// wenn beim schliessen der Verbindung noch was passiert ist das nicht schlimm
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "shutdown connection problem for " + channelName, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// die Schreibverbindung ist kaputt, also diese Connection töten...
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "detected broken connection for " + channelName
|
||||
+ " because Server closed port");
|
||||
connectionClosed();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// wenn beim schliessen der Verbindung noch was passiert ist das nicht schlimm
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "channel shut down finished for " + channelName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Runtime.Remoting.Proxies;
|
||||
using System.Threading;
|
||||
using com.itac.artes.ihap;
|
||||
using com.itac.artes.ihap.serialize;
|
||||
using com.itac.mes.domain;
|
||||
using com.itac.mes.proxy.business;
|
||||
using com.itac.mes.tools;
|
||||
using com.itac.oib;
|
||||
using com.itac.oib.boardgatekeeper.service;
|
||||
using com.itac.oib.linecontrol.service;
|
||||
using com.itac.oib.monitoring.service;
|
||||
using com.itac.oib.siplacesetupcenter.service;
|
||||
using com.itac.oib.traceability.service;
|
||||
|
||||
namespace com.itac.mes.proxy.sockets
|
||||
{
|
||||
|
||||
public delegate void ClientDisconnectedHandler(IhapHandler handler);
|
||||
|
||||
public class IhapHandler : RealProxy
|
||||
{
|
||||
private static IDictionary<String, MethodInfo> _methodMap;
|
||||
private static int handlerCounter;
|
||||
|
||||
private Object lockObject = new Object();
|
||||
|
||||
private int handlerNr;
|
||||
private TcpClient _client;
|
||||
private IhapOutputStream _ios;
|
||||
private IhapInputStream _iis;
|
||||
private OIBServiceImpl _serviceImpl;
|
||||
private bool _isShutdown;
|
||||
private long lastCall = DateTime.Now.Ticks;
|
||||
|
||||
|
||||
public IhapHandler(TcpClient client, OIBServiceImpl oibServiceImpl)
|
||||
: base(typeof(OIBEvents))
|
||||
{
|
||||
lock (typeof(IhapHandler))
|
||||
{
|
||||
handlerCounter++;
|
||||
this.handlerNr = handlerCounter;
|
||||
}
|
||||
this._client = client;
|
||||
this._serviceImpl = oibServiceImpl;
|
||||
|
||||
// damit zum testen callbacks aufgerufen werden koennen
|
||||
initMethodMap();
|
||||
Thread thread = new Thread(new ThreadStart(Run));
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
public event ClientDisconnectedHandler ClientDisconnected;
|
||||
|
||||
private static void initMethodMap()
|
||||
{
|
||||
if (_methodMap != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_methodMap = new Dictionary<String, MethodInfo>();
|
||||
ProtocolMapping protocolMapping = new ProtocolMapping_v1();
|
||||
MethodInfo[] methods = typeof(OIBService).GetMethods();
|
||||
foreach (MethodInfo method in methods)
|
||||
{
|
||||
_methodMap.Add(protocolMapping.getOverloadMethodName(method), method);
|
||||
}
|
||||
|
||||
// Alle Methoden aller implmentierten Interface eintragen...
|
||||
Type[] array = typeof(OIBService).GetInterfaces();
|
||||
foreach (Type innerType in array)
|
||||
{
|
||||
methods = innerType.GetMethods();
|
||||
foreach (MethodInfo method in methods)
|
||||
{
|
||||
_methodMap.Add(protocolMapping.getOverloadMethodName(method), method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown()
|
||||
{
|
||||
_isShutdown = true;
|
||||
try
|
||||
{
|
||||
_serviceImpl.Shutdown();
|
||||
_client.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public long getLastCall()
|
||||
{
|
||||
return lastCall;
|
||||
}
|
||||
|
||||
public bool isConnected()
|
||||
{
|
||||
return _client.Client.Connected;
|
||||
}
|
||||
|
||||
public string getName()
|
||||
{
|
||||
return "IhapHandler" + handlerNr;
|
||||
}
|
||||
|
||||
public bool isShutdownInProgress()
|
||||
{
|
||||
return _isShutdown;
|
||||
}
|
||||
|
||||
public override IMessage Invoke(IMessage message)
|
||||
{
|
||||
lastCall = new DateTime().Ticks;
|
||||
IMethodCallMessage methodMsg = (IMethodCallMessage)message;
|
||||
try
|
||||
{
|
||||
MethodInfo methodInfo = typeof(OIBEvents).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
// der Reihe nach alle Interface durchgehen, die als Callback implementiert sind
|
||||
if (methodInfo == null)
|
||||
{
|
||||
methodInfo = typeof(ISiplaceSetupCenterNotify).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
}
|
||||
if (methodInfo == null)
|
||||
{
|
||||
methodInfo = typeof(ITraceability).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
}
|
||||
if (methodInfo == null)
|
||||
{
|
||||
methodInfo = typeof(ISetupCenterExternalControl).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
}
|
||||
if (methodInfo == null)
|
||||
{
|
||||
methodInfo = typeof(IMonitoringReceiver).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
}
|
||||
if (methodInfo == null)
|
||||
{
|
||||
methodInfo = typeof(ILineControlReceiver).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
}
|
||||
if (methodInfo == null)
|
||||
{
|
||||
methodInfo = typeof(IAdapterNotify).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
}
|
||||
if (methodInfo == null)
|
||||
{
|
||||
methodInfo = typeof(IBoardGateKeeper).GetMethod(methodMsg.MethodName, (Type[])methodMsg.MethodSignature);
|
||||
}
|
||||
|
||||
if (methodInfo == null)
|
||||
{
|
||||
throw new Exception("IHapHandler.cs: methode nicht in den Interfacen gefunden");
|
||||
}
|
||||
|
||||
object[] args = methodMsg.Args;
|
||||
if (methodMsg.MethodName.Equals("Equals"))
|
||||
{
|
||||
return new ReturnMessage(args[0].Equals(this), args, 0, methodMsg.LogicalCallContext, methodMsg);
|
||||
}
|
||||
else if (methodMsg.MethodName.Equals("GetHashCode"))
|
||||
{
|
||||
return new ReturnMessage(this.GetHashCode(), args, 0, methodMsg.LogicalCallContext, methodMsg);
|
||||
}
|
||||
Object retValue = sendCall(methodInfo, args);
|
||||
return new ReturnMessage(retValue, args, 0, methodMsg.LogicalCallContext, methodMsg);
|
||||
}
|
||||
catch (TargetInvocationException ite)
|
||||
{
|
||||
return new ReturnMessage(ite.GetBaseException(), methodMsg);
|
||||
}
|
||||
catch (Exception ite)
|
||||
{
|
||||
return new ReturnMessage(ite.GetBaseException(), methodMsg);
|
||||
}
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
Thread.CurrentThread.Name = "IhapHandler-" + handlerNr;
|
||||
_ios = new IhapOutputStream(_client.GetStream());
|
||||
_iis = new IhapInputStream(_client.GetStream());
|
||||
try
|
||||
{
|
||||
while (!_isShutdown && isConnected())
|
||||
{
|
||||
receiveCall();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void receiveCall()
|
||||
{
|
||||
lock (lockObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
Exception fault = null;
|
||||
Object returnValue = null;
|
||||
String methodName = null;
|
||||
try
|
||||
{
|
||||
if (!_iis.readBoolean())
|
||||
{
|
||||
IhapCall lCall = _iis.readCall();
|
||||
methodName = lCall.getOverloadMethodName();
|
||||
if (_methodMap.ContainsKey(methodName))
|
||||
{
|
||||
MethodInfo lMethod = _methodMap[methodName];
|
||||
Object[] args = lCall.getArgs();
|
||||
returnValue = lMethod.Invoke(_serviceImpl, args);
|
||||
lastCall = DateTime.Now.Ticks;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//ping...
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (IhapProtocolException pe)
|
||||
{
|
||||
if (pe.Message.EndsWith("end of file"))
|
||||
{
|
||||
throw pe;
|
||||
}
|
||||
fault = new ArtesRemoteException("Unable to read client request on " + getName(), pe);
|
||||
_ios.writeFaultReply(FaultCode.ProtocolException, fault);
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
fault = new ArtesRemoteException("Unknown method '" + methodName + "'");
|
||||
_ios.writeFaultReply(FaultCode.NoSuchMethodException, fault);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw ioe;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is TargetInvocationException)
|
||||
{
|
||||
e = ((TargetInvocationException)e).InnerException;
|
||||
}
|
||||
fault = e;
|
||||
_ios.writeFaultReply(FaultCode.ServiceException, fault);
|
||||
}
|
||||
if (fault == null)
|
||||
{
|
||||
_ios.writeSuccessReply(returnValue);
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
if (ioe.Message.EndsWith("end of file"))
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Socket " + _client.Client.RemoteEndPoint + " disconnected for " + getName());
|
||||
ClientDisconnected(this);
|
||||
shutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "Error receiving call for " + getName() + ":" + ioe.Message);
|
||||
ClientDisconnected(this);
|
||||
}
|
||||
throw ioe;
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
_ios.Flush();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object sendCall(MethodInfo method, Object[] args)
|
||||
{
|
||||
lock (lockObject)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "Send event '" + method.Name + "' to socket " + _client.Client.RemoteEndPoint + " for " + getName());
|
||||
Object result = null;
|
||||
try
|
||||
{
|
||||
_ios.writeBoolean(false);
|
||||
_ios.call(method, args);
|
||||
_ios.Flush();
|
||||
IhapReply reply = _iis.readReply();
|
||||
if (reply is IhapSuccessReply)
|
||||
{
|
||||
result = ((IhapSuccessReply)reply).getReturnValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
IhapFaultReply fault = (IhapFaultReply)reply;
|
||||
switch (fault.getFaultCode())
|
||||
{
|
||||
case FaultCode.NoSuchMethodException:
|
||||
throw new NotImplementedException(fault.getMessage());
|
||||
case FaultCode.ProtocolException:
|
||||
throw new IhapProtocolException(fault.getMessage(), null);
|
||||
default:
|
||||
throw new IhapProtocolException(fault.getMessage(), null); // (Exception)fault.getException();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "Error while sending event call for " + getName() + " . " + e.Message + "\n" + e.StackTrace);
|
||||
shutdown();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAdapterControl(IAdapterControl adapterControl)
|
||||
{
|
||||
_serviceImpl.SetAdapterControl(adapterControl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
#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<IhapHandler> _channels = new List<IhapHandler>();
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user