Ejemplo n.º 1
0
        public bool DisconnectClient(int clientId)
        {
            SocketCommunicatorEx client;

            if (_clientsHotSwap.TryGetValue(clientId, out client) == false)
            {
                return(false);
            }

            return(client.DisconnectAsync());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Obtain a collection of the Ids of all clients that implement the interface.
        /// </summary>
        /// <param name="interfaceType"></param>
        /// <returns>The actual hot swap instance, of the collection with the interfaces, thus making it an ultra-fast (instant) result.</returns>
        public ClientId GetFirstInterfaceImplementor(Type interfaceType)
        {
            HotSwapList <ClientId> result = null;

            if (_clientsInterfaces.TryGetValue(interfaceType, out result) == false)
            {
                return(null);
            }

            if (result.Count > 0)
            {
                return(result[0]);
            }

            return(null);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Will return negative value (for ex. -1, or see InvalidClientIndex) to indicate not found.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        protected int GetClientIndexByGuid(Guid guid)
        {
            int result = 0;

            if (_guidToIndexHotSwap.TryGetValue(guid, out result) == false)
            {
                return(ClientId.InvalidMessageBusClientIndex);
            }

            return(result);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Obtain a list of the receivers of the event raise.
        /// </summary>
        /// <param name="specific">True to get the specific for this one, false to get the "subscribe to all"</param>
        public HotSwapDictionary <ClientId, ClientEventSubscriptionInfo> GetReceivers(ClientId sourceId, bool specific)
        {
            HotSwapDictionary <ClientId, ClientEventSubscriptionInfo> result;

            if (specific)
            {
                if (_subscriptionsHotSwap.TryGetValue(sourceId, out result) == false)
                {// If not found, return an empty one.
                    result = new HotSwapDictionary <ClientId, ClientEventSubscriptionInfo>();
                }
            }
            else
            {
                if (_subscriptionsHotSwap.TryGetValue(SubscribeToAllId, out result) == false)
                {// If not found, return an empty one.
                    result = new HotSwapDictionary <ClientId, ClientEventSubscriptionInfo>();
                }
            }

            return(result);
        }
Ejemplo n.º 5
0
        public override List <string> GetClientSourceTypes(ClientId clientId)
        {
            if (clientId.IsMessageBusIndexValid && clientId.MessageBus == this)
            {// Seems to be a local client Id.
                return(base.GetClientSourceTypes(clientId));
            }

            List <string> names;

            if (_originalServerClientsSourcesTypesHotNamesSwap.TryGetValue(clientId.Guid, out names))
            {
                return(names);
            }

            return(null);
        }
Ejemplo n.º 6
0
        public override Type GetClientType(ClientId clientId)
        {
            if (clientId.IsMessageBusIndexValid && clientId.MessageBus == this)
            {// Seems to be a local client Id.
                return(base.GetClientType(clientId));
            }

            Type value;

            if (_originalServerClientsTypesHotSwap.TryGetValue(clientId.Guid, out value))
            {
                return(value);
            }

            return(null);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Implementation, separate in order to allow calls from child classes.
        /// </summary>
        public static object GetTypeDefaultValue(Type returnType)
        {
            if (returnType == null || returnType.IsByRef ||
                returnType.IsClass)
            {
                return(null);
            }

            object result;

            if (_defaultReturnValues.TryGetValue(returnType, out result))
            {
                return(result);
            }

            result = Activator.CreateInstance(returnType);
            _defaultReturnValues.Add(returnType, result);

            return(result);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// An event (with return value) was raised by our source.
        /// </summary>
        public object ReceiveDynamicMethodCallAndReturn(int methodId, Type returnType, object[] parameters)
        {
            EventHandlingInformation eventSubscriptionInfo;

            if (_eventsMethods.TryGetValue(methodId, out eventSubscriptionInfo) == false)
            {
#if Matrix_Diagnostics
                SystemMonitor.OperationError("Failed to find corresponding method info, invocation aborted (possible dispose).");
#endif
                return(ProxyTypeManager.GetTypeDefaultValue(returnType));
            }

            SuperPoolSubscription owner = _owner;
            if (owner == null)
            {
#if Matrix_Diagnostics
                SystemMonitor.OperationError("Owner not assign, invocation aborted (possible dispose).");
#endif
                return(ProxyTypeManager.GetTypeDefaultValue(returnType));
            }

            return(owner.ProcessEventRaised(this, eventSubscriptionInfo, returnType, parameters));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Basic asynchronous call operation.
        /// </summary>
        /// <param name="receiverId">The value of the receiver, null means call all.</param>
        internal bool Call <InterfaceType>(SuperPoolClient sender, IEnumerable <ComponentId> receiversIds,
                                           out InterfaceType result, out SuperPoolProxyCall call)
            where InterfaceType : class
        {
            call   = null;
            result = null;

            // SLOW.
            //if (_messageBus.ContainsClient(sender.Id) == false)
            //{
            //    SystemMonitor.OperationError("Client not a member of message bus (and super pool).");
            //    return false;
            //}

            if (typeof(InterfaceType).IsInterface == false)
            {
                throw new Exception("Type provided not an interface.");
            }

            // Very slow !!
            //object[] attributes = typeof(InterfaceType).GetCustomAttributes(typeof(SuperPoolInterfaceAttribute), false);
            //if (attributes == null || attributes.Length == 0)
            //{
            //    SystemMonitor.Throw("Interface type [" + typeof(InterfaceType).Name + "] not marked as super pool interface.");
            //    return false;
            //}

            ProxyTypeManager typeManager = _proxyTypeManager;

            if (typeManager == null)
            {
                return(false);
            }

            if (_pendingThreadsCalls.TryGetValue(Thread.CurrentThread.ManagedThreadId, out call) == false)
            {// We are safe from danger of someone else already adding the value with this id,
                // since we are the only thread with this id.
                call = new SuperPoolProxyCall();
                // This is slow, but very rarely executed, since thread ids are reused.
                _pendingThreadsCalls.Add(Thread.CurrentThread.ManagedThreadId, call);
            }
            else
            {
                // Since we reuse the call, clean it up before usage.
                call.Clear();
            }

            call.Processed = false;
            if (receiversIds != null)
            {// Extract the Indeces from the Ids.
                List <ClientId> receiversIndeces = new List <ClientId>();
                foreach (ComponentId id in receiversIds)
                {
                    receiversIndeces.Add((ClientId)id);
                }

                call.ReceiversIds = receiversIndeces;
            }
            else
            {
                call.ReceiversIds = null;
            }

            call.Sender = sender;

            result = (InterfaceType)typeManager.ObtainInterfaceProxy(typeof(InterfaceType));

            return(true);
        }
Ejemplo n.º 10
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);
        }