Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        bool RegisterClientSourceTypes(ClientId clientId)
        {
            IMessageBus messageBus = _messageBus;

            if (messageBus == null)
            {
                Console.WriteLine("Failed to register client source type, message bus not found.");
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to register client source type, message bus not found.");
#endif
                return(false);
            }

            List <string> sourceTypes = messageBus.GetClientSourceTypes(clientId);
            if (sourceTypes == null)
            {
                Console.WriteLine("Failed to register client source type, source type not found.");
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to register client source type, source type not found.");
#endif
                return(false);
            }

            foreach (Type superType in ReflectionHelper.GetKnownTypes(sourceTypes))
            {
                if (superType.IsInterface == false ||
                    ReflectionHelper.TypeHasCustomAttribute(superType, typeof(SuperPoolInterfaceAttribute), false) == false)
                {
                    continue;
                }

                HotSwapList <ClientId> clientList = null;
                if (_clientsInterfaces.TryGetValue(superType, out clientList) == false)
                {
                    clientList = _clientsInterfaces.GetOrAdd(superType, new HotSwapList <ClientId>());
                }

                clientList.AddUnique(clientId);

                if (ReflectionHelper.TypeHasCustomAttribute(superType, typeof(SuperPoolInterfaceAttribute), false) == false)
                {// Register this type as well.
                    _proxyTypeManager.ObtainInterfaceProxy(superType);
                }
            }

            return(true);
        }
Esempio n. 2
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);
        }