Esempio n. 1
0
        /// <summary>
        /// Client source has raised an event, process it.
        /// </summary>
        internal object ProcessEventRaised(ClientEventsHandler client,
                                           ClientEventsHandler.EventHandlingInformation eventSubscriptionInfo, Type returnType, object[] parameters)
        {
            if (string.IsNullOrEmpty(eventSubscriptionInfo.GeneratedMethodInfo.EventName))
            {
                // Establish the name of the event.
                eventSubscriptionInfo.GeneratedMethodInfo.EventName =
                    GeneralHelper.GetEventMethodExtendedName(eventSubscriptionInfo.EventInfo, false);
            }

            EventSubscriptionInfo eventSubscription = null;

            if (string.IsNullOrEmpty(eventSubscriptionInfo.GeneratedMethodInfo.EventName) == false &&
                _eventSubscriptions.TryGetValue(eventSubscriptionInfo.GeneratedMethodInfo.EventName, out eventSubscription))
            {// OK, to perform the calls.
                // Process specific subscribers
                foreach (KeyValuePair <ClientId, EventSubscriptionInfo.ClientEventSubscriptionInfo> pair
                         in eventSubscription.GetReceivers(client.Client.Id, true))
                {
                    foreach (KeyValuePair <MethodInfo, int> subPair in pair.Value.Data)
                    {
                        for (int i = 0; i < subPair.Value; i++)
                        {     // May need to raise multiple times.
                            if (client.Client.Id != pair.Key)
                            { // Filter out subscriptions by the one that raised it.
                                ProcessEventCall(client.Client.Id, pair.Key, subPair.Key, parameters);
                            }
                        }
                    }
                }

                // Process subscribe to all.
                foreach (KeyValuePair <ClientId, EventSubscriptionInfo.ClientEventSubscriptionInfo> pair
                         in eventSubscription.GetReceivers(client.Client.Id, false))
                {
                    foreach (KeyValuePair <MethodInfo, int> subPair in pair.Value.Data)
                    {
                        for (int i = 0; i < subPair.Value; i++)
                        {     // May need to raise multiple times.
                            if (client.Client.Id != pair.Key)
                            { // Filter out subscriptions by the one that raised it.
                                ProcessEventCall(client.Client.Id, pair.Key, subPair.Key, parameters);
                            }
                        }
                    }
                }
            }
            else
            {// No subscription(s) for this event.
#if Matrix_Diagnostics
                InstanceMonitor.Info(string.Format("Event raised [{0}] had no subscribers.", eventSubscriptionInfo.GeneratedMethodInfo.EventName), TracerItem.PriorityEnum.Trivial);
#endif
            }

            // Return a default value.
            return(ProxyTypeManager.GetTypeDefaultValue(returnType));
        }
Esempio n. 2
0
        /// <summary>
        /// Remove all subscription references for this client.
        /// </summary>
        /// <returns></returns>
        protected override bool HandleClientRemoved(IMessageBus messageBus, ClientId clientId, bool isPermanent)
        {
            if (base.HandleClientRemoved(messageBus, clientId, isPermanent) == false)
            {
                return(false);
            }

            if (isPermanent)
            {// Only cleanup subscriptions in case remove was permanent.
                foreach (EventSubscriptionInfo subscription in _eventSubscriptions.Values)
                {
                    subscription.RemoveClientSubscriptions(clientId);
                }
            }

            ClientEventsHandler clientInfo = null;

            lock (_syncRoot)
            {
                if (_clients.TryGetValue(clientId, out clientInfo) == false)
                {// Client not added, possibly not a local client.
                    return(true);
                }

                if (_clients.Remove(clientId) == false)
                {
#if Matrix_Diagnostics
                    InstanceMonitor.OperationError("Failed to remove client from subscription lists.");
#endif
                }
            }

            if (clientInfo != null)
            {
                clientInfo.Dispose();
            }

            return(true);
        }
Esempio n. 3
0
        protected override bool HandleClientAdded(IMessageBus messageBus, ClientId clientId)
        {
            // Make sure to have this done first, since it will send notifications of clients, and we
            // may need those for the establishment of events.
            if (base.HandleClientAdded(messageBus, clientId) == false || messageBus == null || clientId == null)
            {
                return(false);
            }

            MessageBusClient clientInstance = messageBus.GetLocalClientInstance(clientId);

            // Will only work for local AND MessageSuperPoolClient typed clients.
            if (clientInstance is SuperPoolClient)
            {
                lock (_syncRoot)
                {
                    if (_clients.ContainsKey(clientInstance.Id))
                    {// Already added.
                        return(false);
                    }

                    ClientEventsHandler subscription = new ClientEventsHandler(this, (SuperPoolClient)clientInstance);
                    _clients.Add(clientInstance.Id, subscription);
                }
            }
            else
            {
                List <string> sourceTypeNames = messageBus.GetClientSourceTypes(clientId);
                if (sourceTypeNames == null)
                {
#if Matrix_Diagnostics
                    InstanceMonitor.Error("Failed to obtain client [" + clientId.ToString() + "] source type.");
#endif
                    return(false);
                }

                SuperPoolClient intercomClient = IntercomClient;
                if (intercomClient == null)
                {
#if Matrix_Diagnostics
                    InstanceMonitor.Error("Failed to obtain super pool main intercom client, so new client handling has failed.");
#endif
                    return(false);
                }

                List <EventSubscriptionRequest> totalRequests = new List <EventSubscriptionRequest>();
                if (clientId.IsLocalClientId == false)
                {
                    // Gather all the Super Pool related interfaces and their events, and send global updates for those
                    // so that any pending subscriptions may be restored.
                    // This is only done where the client is a remote client instance, since local ones we already know
                    // of them. This eventing information must be at the local pool for the client, since it is the one
                    // handling the event and sending it to all interested parties.
                    foreach (Type interfaceType in ReflectionHelper.GetKnownTypes(sourceTypeNames))
                    {
                        if (interfaceType.IsInterface &&
                            ReflectionHelper.TypeHasCustomAttribute(interfaceType, typeof(SuperPoolInterfaceAttribute), false) == false)
                        {// Interface type not marked as super pool.
                            continue;
                        }

                        foreach (EventInfo info in interfaceType.GetEvents())
                        {
                            string eventName = GeneralHelper.GetEventMethodExtendedName(info, false);
                            EventSubscriptionInfo eventInfo;
                            if (_eventSubscriptions.TryGetValue(eventName, out eventInfo))
                            {
                                totalRequests.AddRange(eventInfo.GatherSourceRelatedUpdates(clientId));
                            }
                        }
                    }
                }

                // Send updates for the newly connected client, so that it can obtain any subscription information
                // regarding it, it case it has missed some.
                foreach (EventSubscriptionRequest request in totalRequests)
                {
                    // Notify other connected super pools of this subcription,
                    // since the subscribee(s) may be attached on them.
                    // *pendingCall swap done here, make sure to not use it on or after this line*
                    intercomClient.CallAll <ISuperPoolIntercom>().ProcessSubscriptionUpdate(request);
                }
            }


            return(true);
        }