/// <summary> /// Invokes a remote method. /// </summary> /// <param name="methodCallMessage">Remoting message.</param> /// <returns>Remoting response message</returns> private ReturnMessage InvokeRemoteMethod(IMethodCallMessage methodCallMessage) { Guid trackingID = Guid.NewGuid(); try { object returnValue = null; List <DelegateCorrelationInfo> correlationSet = null; if (_activationType == ActivationType.SingleCall) { correlationSet = _delegateCorrelationSet; } BeforeInvokeEventArgs cancelArgs = new BeforeInvokeEventArgs() { TrackingID = trackingID, InterfaceName = _interfaceType.FullName, DelegateCorrelationSet = correlationSet, MethodName = methodCallMessage.MethodName, Arguments = methodCallMessage.Args, Cancel = false }; _connection.OnBeforeInvoke(cancelArgs); if (cancelArgs.Cancel) { if (cancelArgs.CancelException == null) { cancelArgs.CancelException = new InvokeCanceledException(); } _connection.OnInvokeCanceled(new InvokeCanceledEventArgs() { TrackingID = trackingID, CancelException = cancelArgs.CancelException }); throw cancelArgs.CancelException.PreserveStackTrace(); } // Prepare generic method arguments Type[] genericArgs = null; if (methodCallMessage.MethodBase.IsGenericMethod) { genericArgs = methodCallMessage.MethodBase.GetGenericArguments(); } var paramDefs = methodCallMessage.MethodBase.GetParameters(); var paramTypes = paramDefs.Select(p => p.ParameterType).ToArray(); try { object[] checkedArgs = InterceptDelegateParameters(methodCallMessage); returnValue = _remoteDispatcher.Invoke(trackingID, _uniqueName, correlationSet, methodCallMessage.MethodName, genericArgs, paramTypes, checkedArgs); AfterInvokeEventArgs afterInvokeArgs = new AfterInvokeEventArgs() { TrackingID = trackingID, InterfaceName = _interfaceType.FullName, DelegateCorrelationSet = correlationSet, MethodName = methodCallMessage.MethodName, Arguments = methodCallMessage.Args, ReturnValue = returnValue }; _connection.OnAfterInvoke(afterInvokeArgs); } catch (InvalidSessionException) { if (_autoLoginOnExpiredSession) { if (_connection.Reconnect()) { returnValue = _remoteDispatcher.Invoke(trackingID, _uniqueName, correlationSet, methodCallMessage.MethodName, genericArgs, paramTypes, methodCallMessage.Args); } else { throw; } } else { throw; } } var container = returnValue as CustomSerializationContainer; if (container != null) { var serializationHandler = _connection.SerializationHandling[container.HandledType]; if (serializationHandler == null) { throw new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_SerializationHandlerNotFound, container.HandledType.FullName)); } returnValue = serializationHandler.Deserialize(container.DataType, container.Data); } return(new ReturnMessage(returnValue, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage)); } catch (Exception ex) { if (_connection.ErrorHandlingEnabled) { throw; } else { return(new ReturnMessage(ex, methodCallMessage)); } } }
/// <summary> /// Führt einen entfernten Methodenaufruf aus. /// </summary> /// <param name="methodCallMessage">Remoting-Nachricht mit Details für den entfernten Methodenaufruf</param> /// <returns>Remoting Antwortnachricht</returns> private IMessage InvokeRemoteMethod(IMethodCallMessage methodCallMessage) { // Aufrufschlüssel vergeben Guid trackingID = Guid.NewGuid(); try { // Variable für Rückgabewert object returnValue = null; // Variable für Verdrahtungskorrelationssatz List <DelegateCorrelationInfo> correlationSet = null; // Wenn die Komponente SingleCallaktiviert ist ... if (_activationType == ActivationType.SingleCall) { // Korrelationssatz übernehmen (wird mit übertragen) correlationSet = _delegateCorrelationSet; } // Ereignisargumente für BeforeInvoke erstellen BeforeInvokeEventArgs cancelArgs = new BeforeInvokeEventArgs() { TrackingID = trackingID, InterfaceName = _interfaceType.FullName, DelegateCorrelationSet = correlationSet, MethodName = methodCallMessage.MethodName, Arguments = methodCallMessage.Args, Cancel = false }; // BeforeInvoke-Ereignis feuern _connection.OnBeforeInvoke(cancelArgs); // Wenn der Aufruf abgebrochen werden soll ... if (cancelArgs.Cancel) { // Wenn keine Abbruchausnahme definiert ist ... if (cancelArgs.CancelException == null) { // Standard-Abbruchausnahme erstellen cancelArgs.CancelException = new InvokeCanceledException(); } // InvokeCanceled-Ereignis feuern _connection.OnInvokeCanceled(new InvokeCanceledEventArgs() { TrackingID = trackingID, CancelException = cancelArgs.CancelException }); // Abbruchausnahme werfen throw cancelArgs.CancelException; } // Parametertypen ermitteln ParameterInfo[] paramDefs = methodCallMessage.MethodBase.GetParameters(); try { // Ggf. Delegaten-Parameter abfangen object[] checkedArgs = InterceptDelegateParameters(methodCallMessage); // Entfernten Methodenaufruf durchführen returnValue = _remoteInvoker.Invoke(trackingID, _interfaceType.FullName, correlationSet, methodCallMessage.MethodName, paramDefs, checkedArgs); // Ereignisargumente für AfterInvoke erstellen AfterInvokeEventArgs afterInvokeArgs = new AfterInvokeEventArgs() { TrackingID = trackingID, InterfaceName = _interfaceType.FullName, DelegateCorrelationSet = correlationSet, MethodName = methodCallMessage.MethodName, Arguments = methodCallMessage.Args, ReturnValue = returnValue }; // AfterInvoke-Ereignis feuern _connection.OnAfterInvoke(afterInvokeArgs); } catch (InvalidSessionException) { // Wenn automatisches Anmelden bei abgelaufener Sitzung aktiviert ist ... if (_autoLoginOnExpiredSession) { // Neu anmelden _remoteInvoker.Logon(_sessionID, _autoLoginCredentials); // Entfernten Methodenaufruf erneut versuchen returnValue = _remoteInvoker.Invoke(trackingID, _interfaceType.FullName, correlationSet, methodCallMessage.MethodName, paramDefs, methodCallMessage.Args); } } // Remoting-Antwortnachricht erstellen und zurückgeben return(new ReturnMessage(returnValue, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage)); } catch (TargetInvocationException targetInvocationException) { // Aufrufausnahme als Remoting-Nachricht zurückgeben return(new ReturnMessage(targetInvocationException, methodCallMessage)); } catch (SocketException socketException) { // TCP-Sockelfehler als Remoting-Nachricht zurückgeben return(new ReturnMessage(socketException, methodCallMessage)); } catch (InvalidSessionException sessionException) { // Sitzungsfehler als Remoting-Nachricht zurückgeben return(new ReturnMessage(sessionException, methodCallMessage)); } }