예제 #1
0
        /// <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));
                }
            }
        }
예제 #2
0
        /// <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));
            }
        }