344 lines
12 KiB
C#
344 lines
12 KiB
C#
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);
|
|
}
|
|
|
|
}
|
|
|
|
}
|