Beispiel #1
0
        /// <summary>
        /// Adds a handler to an event of a server component.
        /// </summary>
        /// <param name="interfaceName">Name of the server component interface</param>
        /// <param name="correlation">Correlation information</param>
        /// <param name="uniqueName">Unique name of the server component instance (May left empty, if component isn´t registered with a unique name)</param>
        /// <param name="callContext">Call context data</param>
        public void AddEventHandler(string interfaceName, DelegateCorrelationInfo correlation, string uniqueName, LogicalCallContextData callContext)
        {
            if (string.IsNullOrEmpty(interfaceName))
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");

            if (string.IsNullOrEmpty(uniqueName))
                uniqueName = interfaceName;

            if (!_host.ComponentRegistry.ContainsKey(uniqueName))
                throw new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_CannotFindComponentForInterface, interfaceName));

            var details = new InvocationDetails()
            {
                InterfaceName = interfaceName,
                Registration = _host.ComponentRegistry[uniqueName],
                CallContextData = callContext
            };

            Invoke_LoadCallContextData(details);
            Invoke_SetSession(details);
            Invoke_ResolveComponentInstance(details);

            var correlationSet = new List<DelegateCorrelationInfo>
            {
                correlation
            };

            CreateClientServerWires(details.Type, details.Registration.EventStub, correlationSet, details.Registration.EventWirings);
        }
Beispiel #2
0
        /// <summary>
        /// Bereitet den Aufrufkontext für die Übertragung vor.
        /// </summary>
        internal void PrepareCallContext(bool implicitTransactionTransfer)
        {
            // Transferobjekt für Kontextdaten erzeugen, die implizit übertragen werden sollen
            LogicalCallContextData data = new LogicalCallContextData();

            // Sitzungsschlüssel im Transferobjekt ablegen
            data.Store.Add("sessionid", _sessionID);

            // Wenn eine Umgebungstransaktion aktiv ist die implizite Transaktionsübertragung eingeschaltet ist ...
            if (implicitTransactionTransfer && Transaction.Current != null)
            {
                // Umgebungstransaktion abrufen
                Transaction transaction = Transaction.Current;

                // Wenn die Transaktion noch aktiv ist ...
                if (transaction.TransactionInformation.Status == TransactionStatus.InDoubt ||
                    transaction.TransactionInformation.Status == TransactionStatus.Active)
                {
                    // Transaktion im Transferobjekt ablegen
                    data.Store.Add("transaction", transaction);
                }
            }
            // Transferobjekt in den Aufrufkontext einhängen
            CallContext.SetData("__ZyanContextData_" + _componentHostName, data);
        }
        /// <summary>
        /// Called from client to send a heartbeat signal.
        /// </summary>
        /// <param name="sessionID">Client´s session key</param>
        /// <param name="callContext">Call context data</param>
        public void ReceiveClientHeartbeat(Guid sessionID, LogicalCallContextData callContext)
        {
            // validate server session
            var details = new InvocationDetails();

            details.CallContextData = callContext;
            //Invoke_LoadCallContextData(details);
            Invoke_SetSession(details);

            // fire the heartbeat event
            OnClientHeartbeatReceived(new ClientHeartbeatEventArgs(DateTime.Now, sessionID));
        }
Beispiel #4
0
        /// <summary>
        /// Verlängert die Sitzung des Aufrufers und gibt die aktuelle Sitzungslebensdauer zurück.
        /// </summary>
        /// <returns>Sitzungslebensdauer (in Minuten)</returns>
        public int RenewSession()
        {
            // Kontextdaten aus dem Aufrufkontext lesen (Falls welche hinterlegt sind)
            LogicalCallContextData data = CallContext.GetData("__ZyanContextData_" + _host.Name) as LogicalCallContextData;

            // Wenn Kontextdaten übertragen wurden ...
            if (data != null)
            {
                // Wenn ein Sitzungsschlüssel übertragen wurde ...
                if (data.Store.ContainsKey("sessionid"))
                {
                    // Sitzungsschlüssel lesen
                    Guid sessionID = (Guid)data.Store["sessionid"];

                    // Wenn eine Sitzung mit dem angegebenen Schlüssel existiert ...
                    if (_host.SessionManager.ExistSession(sessionID))
                    {
                        // Sitzung abrufen
                        ServerSession session = _host.SessionManager.GetSessionBySessionID(sessionID);

                        // Sitzung verlängern
                        session.Timestamp = DateTime.Now;

                        // Aktuelle Sitzung im Threadspeicher ablegen
                        ServerSession.CurrentSession = session;
                    }
                    else
                    {
                        // Ausnahme erzeugen
                        InvalidSessionException ex = new InvalidSessionException(string.Format("Sitzungsschlüssel '{0}' ist ungültig! Bitte melden Sie sich erneut am Server an.", sessionID.ToString()));

                        // Ausnahme werfen
                        throw ex;
                    }
                }
            }
            else
            {
                // Ausnahme erzeugen
                SecurityException ex = new SecurityException(LanguageResource.SecurityException_ContextInfoMissing);

                // Ausnahme werfen
                throw ex;
            }
            // Sitzungslebensdauer zurückgeben
            return(SessionAgeLimit);
        }
Beispiel #5
0
        /// <summary>
        /// Prepares the .NET Remoting call context before a remote call.
        /// </summary>
        internal LogicalCallContextData PrepareCallContext(bool implicitTransactionTransfer)
        {
            LogicalCallContextData data = new LogicalCallContextData();

            data.Store.Add("sessionid", _sessionID);

            if (implicitTransactionTransfer && Transaction.Current != null)
            {
                Transaction transaction = Transaction.Current;

                if (transaction.TransactionInformation.Status == TransactionStatus.InDoubt ||
                    transaction.TransactionInformation.Status == TransactionStatus.Active)
                {
                    data.Store.Add("transaction", transaction);
                }
            }
            return(data);
        }
Beispiel #6
0
        /// <summary>
        /// Prepares the .NET Remoting call context before a remote call.
        /// </summary>
        internal void PrepareCallContext(bool implicitTransactionTransfer)
        {
            LogicalCallContextData data = new LogicalCallContextData();

            data.Store.Add("sessionid", _sessionID);

            if (implicitTransactionTransfer && Transaction.Current != null)
            {
                Transaction transaction = Transaction.Current;

                if (transaction.TransactionInformation.Status == TransactionStatus.InDoubt ||
                    transaction.TransactionInformation.Status == TransactionStatus.Active)
                {
                    data.Store.Add("transaction", transaction);
                }
            }

            CallContext.SetData("__ZyanContextData_" + _componentHostName, data);
        }
Beispiel #7
0
        /// <summary>
        /// Called from client to send a heartbeat signal.
        /// </summary>
        /// <param name="sessionID">Client´s session key</param>
        /// <param name="callContext">Call context data</param>
        public void ReceiveClientHeartbeat(Guid sessionID, LogicalCallContextData callContext)
        {
            // validate server session
            var details = new InvocationDetails();
            details.CallContextData = callContext;
            //Invoke_LoadCallContextData(details);
            Invoke_SetSession(details);

            // fire the heartbeat event
            OnClientHeartbeatReceived(new ClientHeartbeatEventArgs(DateTime.Now, sessionID));
        }
Beispiel #8
0
        /// <summary>
        /// Processes remote method invocation.
        /// </summary>
        /// <param name="trackingID">Key for call tracking</param>
        /// <param name="interfaceName">Name of the component interface</param>
        /// <param name="delegateCorrelationSet">Correlation set for dynamic event and delegate wiring</param>
        /// <param name="methodName">Name of the invoked method</param>
        /// <param name="genericArguments">Generic arguments of the invoked method</param>
        /// <param name="paramTypes">Parameter types</param>
        /// <param name="callContext">Call context data</param>
        /// <param name="args">Parameter values</param>
        /// <returns>Return value</returns>
        public object Invoke(Guid trackingID, string interfaceName, List<DelegateCorrelationInfo> delegateCorrelationSet, string methodName, Type[] genericArguments, Type[] paramTypes, LogicalCallContextData callContext, params object[] args)
        {
            if (string.IsNullOrEmpty(interfaceName))
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");

            if (string.IsNullOrEmpty(methodName))
                throw new ArgumentException(LanguageResource.ArgumentException_MethodNameMissing, "methodName");

            // Reset session variable (May point to wrong session, if threadpool thread is reused)
            ServerSession.CurrentSession = null;

            var details = new InvocationDetails()
            {
                TrackingID = trackingID,
                InterfaceName = interfaceName,
                DelegateCorrelationSet = delegateCorrelationSet,
                MethodName = methodName,
                GenericArguments = genericArguments,
                ParamTypes = paramTypes,
                Args = args,
                CallContextData = callContext
            };

            var beforeInvokeOccured = false;

            try
            {
                //Invoke_LoadCallContextData(details);
                Invoke_SetSession(details);
                Invoke_SetTransaction(details);

                beforeInvokeOccured = true;
                ProcessBeforeInvoke(details);

                Invoke_CheckInterfaceName(details);
                Invoke_ConvertMethodArguments(details);
                Invoke_ResolveComponentInstance(details);
                Invoke_ObtainMethodMetadata(details);
                Invoke_InterceptDelegateParams(details);

                details.ReturnValue = details.MethodInfo.Invoke(details.Instance, details.Args, details.MethodInfo.IsOneWay());

                Invoke_ApplyCustomSerializationOnReturnValue(details);
            }
            catch (Exception ex)
            {
                if (beforeInvokeOccured)
                    Invoke_FireInvokeCanceledEvent(details, ex);
                else
                    Invoke_FireInvokeRejectedEvent(details, ex);
            }
            finally
            {
                Invoke_CompleteTransactionScope(details);
                Invoke_CleanUp(details);
            }

            ProcessAfterInvoke(details);

            return details.ReturnValue;
        }
Beispiel #9
0
        internal object SendRemoteMethodCallMessage(Guid trackingID, string uniqueName, List <DelegateCorrelationInfo> correlationSet, string methodName, Type[] genericArgs, Type[] paramTypes, object[] paramValues, LogicalCallContextData callContextData)
        {
            var rpcResponseMessage = _transportAdapter.SendRequest(new RequestMessage()
            {
                RequestType            = RequestType.RemoteMethodCall,
                TrackingID             = trackingID,
                Address                = _serverUrl,
                DelegateCorrelationSet = correlationSet,
                GenericArguments       = genericArgs,
                InterfaceName          = uniqueName,
                MethodName             = methodName,
                ParameterTypes         = paramTypes,
                ParameterValues        = paramValues,
                CallContext            = callContextData
            });

            return(rpcResponseMessage.ReturnValue);
        }
        /// <summary>
        /// Removes a handler from an event of a server component.
        /// </summary>
        /// <param name="interfaceName">Name of the server component interface</param>
        /// <param name="correlation">Correlation information</param>
        /// <param name="uniqueName">Unique name of the server component instance (May left empty, if component isn´t registered with a unique name)</param>
        /// <param name="callContext">Call context data</param>
        public void RemoveEventHandler(string interfaceName, DelegateCorrelationInfo correlation, string uniqueName, LogicalCallContextData callContext)
        {
            if (string.IsNullOrEmpty(interfaceName))
            {
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");
            }

            if (string.IsNullOrEmpty(uniqueName))
            {
                uniqueName = interfaceName;
            }

            if (!_host.ComponentRegistry.ContainsKey(uniqueName))
            {
                throw new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_CannotFindComponentForInterface, interfaceName));
            }

            var details = new InvocationDetails()
            {
                InterfaceName   = interfaceName,
                Registration    = _host.ComponentRegistry[uniqueName],
                CallContextData = callContext
            };

            Invoke_LoadCallContextData(details);
            Invoke_SetSession(details);
            Invoke_ResolveComponentInstance(details);

            var correlationSet = new List <DelegateCorrelationInfo>
            {
                correlation
            };

            RemoveClientServerWires(details.Type, details.Registration.EventStub, correlationSet, details.Registration.EventWirings);
        }
        /// <summary>
        /// Processes remote method invocation.
        /// </summary>
        /// <param name="trackingID">Key for call tracking</param>
        /// <param name="interfaceName">Name of the component interface</param>
        /// <param name="delegateCorrelationSet">Correlation set for dynamic event and delegate wiring</param>
        /// <param name="methodName">Name of the invoked method</param>
        /// <param name="genericArguments">Generic arguments of the invoked method</param>
        /// <param name="paramTypes">Parameter types</param>
        /// <param name="callContext">Call context data</param>
        /// <param name="args">Parameter values</param>
        /// <returns>Return value</returns>
        public object Invoke(Guid trackingID, string interfaceName, List <DelegateCorrelationInfo> delegateCorrelationSet, string methodName, Type[] genericArguments, Type[] paramTypes, LogicalCallContextData callContext, params object[] args)
        {
            if (string.IsNullOrEmpty(interfaceName))
            {
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");
            }

            if (string.IsNullOrEmpty(methodName))
            {
                throw new ArgumentException(LanguageResource.ArgumentException_MethodNameMissing, "methodName");
            }

            // Reset session variable (May point to wrong session, if threadpool thread is reused)
            ServerSession.CurrentSession = null;

            var details = new InvocationDetails()
            {
                TrackingID             = trackingID,
                InterfaceName          = interfaceName,
                DelegateCorrelationSet = delegateCorrelationSet,
                MethodName             = methodName,
                GenericArguments       = genericArguments,
                ParamTypes             = paramTypes,
                Args            = args,
                CallContextData = callContext
            };

            var beforeInvokeOccured = false;

            try
            {
                //Invoke_LoadCallContextData(details);
                Invoke_SetSession(details);
                Invoke_SetTransaction(details);

                beforeInvokeOccured = true;
                ProcessBeforeInvoke(details);

                Invoke_CheckInterfaceName(details);
                Invoke_ConvertMethodArguments(details);
                Invoke_ResolveComponentInstance(details);
                Invoke_ObtainMethodMetadata(details);
                Invoke_InterceptDelegateParams(details);

                details.ReturnValue = details.MethodInfo.Invoke(details.Instance, details.Args, details.MethodInfo.IsOneWay());

                Invoke_ApplyCustomSerializationOnReturnValue(details);
            }
            catch (Exception ex)
            {
                if (beforeInvokeOccured)
                {
                    Invoke_FireInvokeCanceledEvent(details, ex);
                }
                else
                {
                    Invoke_FireInvokeRejectedEvent(details, ex);
                }
            }
            finally
            {
                Invoke_CompleteTransactionScope(details);
                Invoke_CleanUp(details);
            }

            ProcessAfterInvoke(details);

            return(details.ReturnValue);
        }
Beispiel #12
0
        /// <summary>
        /// Ruft eine bestimmte Methode einer Komponente auf und übergibt die angegebene Nachricht als Parameter.
        /// Für jeden Aufruf wird temporär eine neue Instanz der Komponente erstellt.
        /// </summary>
        /// <param name="trackingID">Aufrufschlüssel zur Nachverfolgung</param>
        /// <param name="interfaceName">Name der Komponentenschnittstelle</param>
        /// <param name="delegateCorrelationSet">Korrelationssatz für die Verdrahtung bestimmter Delegaten oder Ereignisse mit entfernten Methoden</param>
        /// <param name="methodName">Methodenname</param>
        /// <param name="paramDefs">Parameter-Definitionen</param>
        /// <param name="args">Parameter</param>
        /// <returns>Rückgabewert</returns>
        public object Invoke(Guid trackingID, string interfaceName, List <DelegateCorrelationInfo> delegateCorrelationSet, string methodName, ParameterInfo[] paramDefs, params object[] args)
        {
            // Wenn kein Schnittstellenname angegeben wurde ...
            if (string.IsNullOrEmpty(interfaceName))
            {
                // Ausnahme werfen
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");
            }

            // Wenn kein Methodenname angegben wurde ...
            if (string.IsNullOrEmpty(methodName))
            {
                // Ausnahme werfen
                throw new ArgumentException(LanguageResource.ArgumentException_MethodNameMissing, "methodName");
            }

            // Ggf. BeforeInvoke-Abos verarbeiten
            ProcessBeforeInvoke(trackingID, ref interfaceName, ref delegateCorrelationSet, ref methodName, ref args);

            // Wenn für den angegebenen Schnittstellennamen keine Komponente registriert ist ...
            if (!_host.ComponentRegistry.ContainsKey(interfaceName))
            {
                // Ausnahme erzeugen
                KeyNotFoundException ex = new KeyNotFoundException(string.Format("Für die angegebene Schnittstelle '{0}' ist keine Komponente registiert.", interfaceName));

                // InvokeCanceled-Ereignis feuern
                _host.OnInvokeCanceled(new InvokeCanceledEventArgs()
                {
                    TrackingID = trackingID, CancelException = ex
                });

                // Ausnahme werfen
                throw ex;
            }
            // Komponentenregistrierung abrufen
            ComponentRegistration registration = _host.ComponentRegistry[interfaceName];

            // Komponenteninstanz erzeugen
            object instance = _host.GetComponentInstance(registration);

            // Implementierungstyp abrufen
            Type type = instance.GetType();

            // Auflistung für Ereignisverdrahtungen
            Dictionary <Guid, Delegate> wiringList = null;

            // Wenn die Komponente SingleCallaktiviert ist ...
            if (registration.ActivationType == ActivationType.SingleCall)
            {
                // Auflistung für Ereignisverdrahtungen erzeugen
                wiringList = new Dictionary <Guid, Delegate>();

                // Bei Bedarf Client- und Server-Komponente miteinander verdrahten
                CreateClientServerWires(type, instance, delegateCorrelationSet, wiringList);
            }
            // Transaktionsbereich
            TransactionScope scope = null;

            // Kontextdaten aus dem Aufrufkontext lesen (Falls welche hinterlegt sind)
            LogicalCallContextData data = CallContext.GetData("__ZyanContextData_" + _host.Name) as LogicalCallContextData;

            // Wenn Kontextdaten übertragen wurden ...
            if (data != null)
            {
                // Wenn ein Sitzungsschlüssel übertragen wurde ...
                if (data.Store.ContainsKey("sessionid"))
                {
                    // Sitzungsschlüssel lesen
                    Guid sessionID = (Guid)data.Store["sessionid"];

                    // Wenn eine Sitzung mit dem angegebenen Schlüssel existiert ...
                    if (_host.SessionManager.ExistSession(sessionID))
                    {
                        // Sitzung abrufen
                        ServerSession session = _host.SessionManager.GetSessionBySessionID(sessionID);

                        // Sitzung verlängern
                        session.Timestamp = DateTime.Now;

                        // Aktuelle Sitzung im Threadspeicher ablegen
                        ServerSession.CurrentSession = session;
                    }
                    else
                    {
                        // Ausnahme erzeugen
                        InvalidSessionException ex = new InvalidSessionException(string.Format("Sitzungsschlüssel '{0}' ist ungültig! Bitte melden Sie sich erneut am Server an.", sessionID.ToString()));

                        // InvokeCanceled-Ereignis feuern
                        _host.OnInvokeCanceled(new InvokeCanceledEventArgs()
                        {
                            TrackingID = trackingID, CancelException = ex
                        });

                        // Ausnahme werfen
                        throw ex;
                    }
                }
                // Wenn eine Transaktion übertragen wurde ...
                if (data.Store.ContainsKey("transaction"))
                {
                    // Transaktionsbereich erzeugen
                    scope = new TransactionScope((Transaction)data.Store["transaction"]);
                }
            }
            else
            {
                // Ausnahme erzeugen
                SecurityException ex = new SecurityException(LanguageResource.SecurityException_ContextInfoMissing);

                // InvokeCanceled-Ereignis feuern
                _host.OnInvokeCanceled(new InvokeCanceledEventArgs()
                {
                    TrackingID = trackingID, CancelException = ex
                });

                // Ausnahme werfen
                throw ex;
            }
            // Rückgabewert
            object returnValue = null;

            // Typen-Array (zur Ermittlung der passenden Signatur) erzeugen
            Type[] types = new Type[paramDefs.Length];

            // Auflistung der Indizes von Parametern, für die eine Delegatenverdrahtung notwendig ist
            Dictionary <int, DelegateInterceptor> delegateParamIndexes = new Dictionary <int, DelegateInterceptor>();

            // Alle Parametertypen durchlaufen
            for (int i = 0; i < paramDefs.Length; i++)
            {
                // Typ in Array einfügen
                types[i] = paramDefs[i].ParameterType;

                // Versuchen den aktuellen Parameter in eine Delegaten-Abfangvorrichtung zu casten
                DelegateInterceptor delegateParamInterceptor = args[i] as DelegateInterceptor;

                // Wenn aktuelle Parameter eine Delegaten-Abfangvorrichtung ist ...
                if (delegateParamInterceptor != null)
                {
                    // Parameter der Delegaten-Verdrahtungsliste zufügen
                    delegateParamIndexes.Add(i, delegateParamInterceptor);
                }
            }
            // Ausnahme-Schalter
            bool exceptionThrown = false;

            try
            {
                // Metadaten der aufzurufenden Methode abrufen
                MethodInfo methodInfo = type.GetMethod(methodName, types);

                // Metadaten der Parameter abrufen
                ParameterInfo[] serverMethodParamDefs = methodInfo.GetParameters();

                // Delegaten-Verdrahtungsliste durchlaufen
                foreach (int index in delegateParamIndexes.Keys)
                {
                    // Abfangvorrichtung adressieren
                    DelegateInterceptor delegateParamInterceptor = delegateParamIndexes[index];

                    // Metadaten des passenden Parameters der Serverkomponenten-Methode adressieren
                    ParameterInfo serverMethodParamDef = serverMethodParamDefs[index];

                    // Dynamischen Draht erzeugen
                    object dynamicWire = DynamicWireFactory.Instance.CreateDynamicWire(type, serverMethodParamDef.ParameterType, delegateParamInterceptor);

                    // Typ des dynamischen Drahtes ermitteln
                    Type dynamicWireType = dynamicWire.GetType();

                    // Dynamischen Draht mit Client-Fernsteuerung verdrahten
                    dynamicWireType.GetProperty("Interceptor").SetValue(dynamicWire, delegateParamInterceptor, null);

                    // Delegat zu dynamischem Draht erzeugen
                    Delegate dynamicWireDelegate = Delegate.CreateDelegate(serverMethodParamDef.ParameterType, dynamicWire, dynamicWireType.GetMethod("In"));

                    // Abfangvorrichtung durch dynamischen Draht austauschen
                    args[index] = dynamicWireDelegate;
                }
                // Methode aufrufen
                returnValue = methodInfo.Invoke(instance, args);
            }
            catch (Exception ex)
            {
                // Ausnahme-Schalter setzen
                exceptionThrown = true;

                // InvokeCanceled-Ereignis feuern
                _host.OnInvokeCanceled(new InvokeCanceledEventArgs()
                {
                    TrackingID = trackingID, CancelException = ex
                });

                // Ausnahme weiterwerfen
                throw ex;
            }
            finally
            {
                // Wenn ein Transaktionsbereich existiert ...
                if (scope != null)
                {
                    // Wenn keine Ausnahme aufgetreten ist ...
                    if (!exceptionThrown)
                    {
                        // Transaktionsbereich abschließen
                        scope.Complete();
                    }

                    // Transaktionsbereich entsorgen
                    scope.Dispose();
                }
                // Wenn die Komponente SingleCallaktiviert ist ...
                if (registration.ActivationType == ActivationType.SingleCall)
                {
                    // Verdrahtung aufheben
                    RemoveClientServerWires(type, instance, delegateCorrelationSet, wiringList);
                }
            }
            // Ggf. AfterInvoke-Abos verarbeiten
            ProcessAfterInvoke(trackingID, ref interfaceName, ref delegateCorrelationSet, ref methodName, ref args, ref returnValue);

            // Rückgabewert zurückgeben
            return(returnValue);
        }