Beispiel #1
0
        /// <summary>
        /// Handles remote method invocation.
        /// </summary>
        /// <param name="methodCallMessage"><see cref="IMethodCallMessage"/> to process.</param>
        /// <param name="methodInfo"><see cref="MethodInfo"/> for the method being called.</param>
        /// <returns><see cref="ReturnMessage"/>, if the call is processed successfully, otherwise, false.</returns>
        private ReturnMessage HandleRemoteInvocation(IMethodCallMessage methodCallMessage, MethodInfo methodInfo)
        {
            _connection.PrepareCallContext(_implicitTransactionTransfer);
            var returnMessage = InvokeRemoteMethod(methodCallMessage);

            _connection.CheckRemoteSubscriptionCounter();
            return(returnMessage);
        }
        /// <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 = _connection.SendRemoteMethodCallMessage
                              (
                    trackingID,
                    _uniqueName,
                    correlationSet,
                    methodCallMessage.MethodName,
                    genericArgs,
                    paramTypes,
                    checkedArgs,
                    _connection.PrepareCallContext(_implicitTransactionTransfer)
                              );

                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())
                    {
                        object[] checkedArgs = InterceptDelegateParameters(methodCallMessage);

                        returnValue = _connection.SendRemoteMethodCallMessage
                                      (
                            trackingID,
                            _uniqueName,
                            correlationSet,
                            methodCallMessage.MethodName,
                            genericArgs,
                            paramTypes,
                            checkedArgs,
                            _connection.PrepareCallContext(_implicitTransactionTransfer)
                                      );
                    }
                    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);
            //}
        }
Beispiel #3
0
        /// <summary>
        /// Entfernte Methode aufrufen.
        /// </summary>
        /// <param name="message">Remoting-Nachricht mit Details für den entfernten Methodenaufruf</param>
        /// <returns>Remoting Antwortnachricht</returns>
        public override IMessage Invoke(IMessage message)
        {
            // Wenn keine Nachricht angegeben wurde ...
            if (message == null)
            {
                // Ausnahme werfen
                throw new ArgumentNullException("message");
            }

            // Nachricht in benötigte Schnittstelle casten
            IMethodCallMessage methodCallMessage = (IMethodCallMessage)message;

            // Methoden-Metadaten abrufen
            MethodInfo methodInfo = (MethodInfo)methodCallMessage.MethodBase;

            methodInfo.GetParameters();

            // Wenn die Methode ein Delegat ist ...
            if (methodInfo.ReturnType.Equals(typeof(void)) &&
                methodCallMessage.InArgCount == 1 &&
                methodCallMessage.ArgCount == 1 &&
                methodCallMessage.Args[0] != null &&
                typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType()) &&
                (methodCallMessage.MethodName.StartsWith("set_") || methodCallMessage.MethodName.StartsWith("add_")))
            {
                // Delegat auf zu verdrahtende Client-Methode abrufen
                object receiveMethodDelegate = methodCallMessage.GetArg(0);

                // "set_" wegschneiden
                string propertyName = methodCallMessage.MethodName.Substring(4);

                // Verdrahtungskonfiguration festschreiben
                DelegateInterceptor wiring = new DelegateInterceptor()
                {
                    ClientDelegate = receiveMethodDelegate
                };
                // Korrelationsinformation zusammenstellen
                DelegateCorrelationInfo correlationInfo = new DelegateCorrelationInfo()
                {
                    IsEvent                   = methodCallMessage.MethodName.StartsWith("add_"),
                    DelegateMemberName        = propertyName,
                    ClientDelegateInterceptor = wiring
                };
                // Wenn die Serverkomponente Singletonaktiviert ist ...
                if (_activationType == ActivationType.Singleton)
                {
                    // Ereignis der Serverkomponente abonnieren
                    _connection.RemoteComponentFactory.AddEventHandler(_interfaceType.FullName, correlationInfo);
                }

                // Verdrahtung in der Sammlung ablegen
                _delegateCorrelationSet.Add(correlationInfo);

                // Leere Remoting-Antwortnachricht erstellen und zurückgeben
                return(new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage));
            }
            else if (methodInfo.ReturnType.Equals(typeof(void)) &&
                     methodCallMessage.InArgCount == 1 &&
                     methodCallMessage.ArgCount == 1 &&
                     methodCallMessage.Args[0] != null &&
                     typeof(Delegate).IsAssignableFrom(methodCallMessage.Args[0].GetType()) &&
                     (methodCallMessage.MethodName.StartsWith("remove_")))
            {
                // EBC-Eingangsnachricht abrufen
                object inputMessage = methodCallMessage.GetArg(0);

                // "remove_" wegschneiden
                string propertyName = methodCallMessage.MethodName.Substring(7);

                // Wenn Verdrahtungen gespeichert sind ...
                if (_delegateCorrelationSet.Count > 0)
                {
                    // Verdrahtungskonfiguration suchen
                    DelegateCorrelationInfo found = (from correlationInfo in (DelegateCorrelationInfo[])_delegateCorrelationSet.ToArray()
                                                     where correlationInfo.DelegateMemberName.Equals(propertyName) && correlationInfo.ClientDelegateInterceptor.ClientDelegate.Equals(inputMessage)
                                                     select correlationInfo).FirstOrDefault();

                    // Wenn eine passende Verdrahtungskonfiguration gefunden wurde ...
                    if (found != null)
                    {
                        // Wenn die Serverkomponente SingleCallaktiviert ist ...
                        if (_activationType == ActivationType.SingleCall)
                        {
                            // Verdrahtungskonfiguration entfernen
                            _delegateCorrelationSet.Remove(found);
                        }
                        else
                        {
                            // Ereignisabo entfernen
                            _connection.RemoteComponentFactory.RemoveEventHandler(_interfaceType.FullName, found);
                        }
                    }
                }
                // Leere Remoting-Antwortnachricht erstellen und zurückgeben
                return(new ReturnMessage(null, null, 0, methodCallMessage.LogicalCallContext, methodCallMessage));
            }
            else
            {
                // Aufrufkontext vorbereiten
                _connection.PrepareCallContext(_implicitTransactionTransfer);

                // Entfernten Methodenaufruf durchführen und jede Antwortnachricht sofort über einen Rückkanal empfangen
                return(InvokeRemoteMethod(methodCallMessage));
            }
        }