예제 #1
0
        /// <summary>
        /// Obtain client based on its index.
        /// </summary>
        protected MessageBusClient GetLocalClientByIndex(int id)
        {
            MessageBusClient result = null;

            if (_clientsHotSwap.TryGetValue(id, ref result))
            {
                return(result);
            }

            return(null);
        }
예제 #2
0
        /// <summary>
        /// Helper, works on local clients only.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        protected ClientId GetLocalClientIdByIndex(int id)
        {
            MessageBusClient client = GetLocalClientByIndex(id);

            if (client == null)
            {
                return(null);
            }

            return(client.Id);
        }
예제 #3
0
        /// <summary>
        /// Obtain the type of the client with this id, if client is available.
        /// </summary>
        public override Type GetClientType(ClientId clientId)
        {
            if (clientId.MessageBus != this)
            {
                return(null);
            }

            MessageBusClient client = GetLocalClientByIndex(clientId.LocalMessageBusIndex);

            if (client == null)
            {
                return(null);
            }

            return(client.GetType());
        }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="clientId"></param>
        /// <returns></returns>
        public override List <string> GetClientSourceTypes(ClientId clientId)
        {
            if (clientId.MessageBus != this)
            {
                return(null);
            }

            MessageBusClient client = GetLocalClientByIndex(clientId.LocalMessageBusIndex);

            if (client == null)
            {
                return(null);
            }

            return(ReflectionHelper.GetTypeNameAndRelatedTypes(client.OptionalSourceType));
        }
예제 #5
0
        /// <summary>
        /// Add a client to the message bus.
        /// </summary>
        public override bool AddClient(MessageBusClient client)
        {
            if (client == null)
            {
                return(false);
            }

            if (client.ExecutionStrategy == null)
            {// Assign the client an instance of the default type of execution strategy used.
                client.SetupExecutionStrategy(new ThreadPoolFastExecutionStrategy(true));
            }

            if (DoAddClient(client, client.Id) == ClientId.InvalidMessageBusClientIndex)
            {
                return(false);
            }

            return(true);
        }
예제 #6
0
        /// <summary>
        /// Actually supply the item to client.
        /// </summary>
        /// <param name="senderId"></param>
        /// <param name="receiverId"></param>
        /// <param name="envelope"></param>
        /// <param name="requestConfirm">In local mode we have receival confirmation, so this value is ignored here (as result is always assured true).</param>
        /// <returns></returns>
        protected virtual SendToClientResultEnum DoSendToClient(ClientId senderId, ClientId receiverId,
                                                                Envelope envelope, TimeSpan?requestConfirmTimeout)
        {
            if (receiverId.MessageBus != this)
            {
                //// Maybe this is a "lost" id, try to see if it is one of ours.
                //if (receiverId.MessageBus == null && _guidToIndexHotSwap.ContainsKey(receiverId.Guid))
                //{// Yes!
                //    receiverId.MessageBus = this;
                //}
                return(SendToClientResultEnum.ClientNotFound);
            }

            MessageBusClient client = GetLocalClientByIndex(receiverId.LocalMessageBusIndex);

            if (client == null)
            {
                return(SendToClientResultEnum.ClientNotFound);
            }

            ISerializer serializer = _serializer;

            if (serializer == null)
            {
                return(SendToClientResultEnum.Failure);
            }

            // Duplicate what (if anything) as according to envelope duplication model.
            envelope = envelope.Duplicate(serializer);
            envelope.History.PushStamp(new EnvelopeStamp(PendingStampId, receiverId, senderId));

            if (client.Receive(envelope))
            {
                return(SendToClientResultEnum.Success);
            }
            else
            {
                return(SendToClientResultEnum.Failure);
            }
        }
예제 #7
0
        /// <summary>
        /// Remove a client from the bus.
        /// </summary>
        public override bool RemoveClient(MessageBusClient client, bool isPermanent)
        {
            int id = client.Id.LocalMessageBusIndex;

            lock (_syncRoot)
            {
                if (_clientsHotSwap.Count <= id || id < 0)
                {
#if Matrix_Diagnostics
                    SystemMonitor.OperationError("Failed to remove client from message bus.");
#endif
                    return(false);
                }

                if (_clientsHotSwap[id] != client)
                {
#if Matrix_Diagnostics
                    SystemMonitor.OperationError("Client [" + client.Id.ToString() + "] not removed, since it does not belong to this message bus with this ID.");
#endif
                    return(false);
                }

                // Performs an internal hot swap.
                _clientsHotSwap[id] = null;

                // Performs an internal hot swap.
                _guidToIndexHotSwap[client.Id.Guid] = ClientId.InvalidMessageBusClientIndex;
            }

            client.UpdateEvent -= new MessageBusClient.ClientUpdateDelegate(client_UpdateEvent);
            client.ReleaseMessageBus();

            RaiseClientRemovedEvent(client.Id, isPermanent);

            return(true);
        }
예제 #8
0
 protected virtual void client_UpdateEvent(MessageBusClient client)
 {
     RaiseClientUpdateEvent(client.Id);
 }
예제 #9
0
 protected virtual void client_UpdateEvent(MessageBusClient client)
 {
     RaiseClientUpdateEvent(client.Id);
 }
예제 #10
0
        /// <summary>
        /// Needs to consume both client and id, since it may be used with client == null.
        /// </summary>
        /// <returns>The index of the newly registered client, or InvalidClientIndex on failure.</returns>
        protected int DoAddClient(MessageBusClient client, ClientId clientId)
        {
            int index = 0;

            if (client != null && client.Id.Equals(clientId) == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Error("Client id mismatch.");
#endif
                return(ClientId.InvalidMessageBusClientIndex);
            }

            lock (_syncRoot)
            {
                if (clientId.LocalMessageBusIndex != ClientId.InvalidMessageBusClientIndex)
                {// Client already has an Index assigned, must reuse it.
                    MessageBusClient existingInstance = null;
                    if (_clientsHotSwap.TryGetValue(clientId.LocalMessageBusIndex, ref existingInstance))
                    {// Successfully acquired existing value for client.
                        // Check if we are OK to assign to this position.
                        if (existingInstance != null && existingInstance != client)
                        {// There is something else at that position.
#if Matrix_Diagnostics
                            InstanceMonitor.Error("Client id mismatch.");
#endif
                            return(ClientId.InvalidMessageBusClientIndex);
                        }
                    }
                    else
                    {// Failed to acquire value with this message bus index.
#if Matrix_Diagnostics
                        InstanceMonitor.Error("Client with this message bus index can not be assigned.");
#endif
                        return(ClientId.InvalidMessageBusClientIndex);
                    }

                    // Assign the client to its former spot.
                    _clientsHotSwap[clientId.LocalMessageBusIndex] = client;
                    index = clientId.LocalMessageBusIndex;
                }
                else
                {
                    if (GetClientIndexByGuid(clientId.Guid) >= 0)
                    {// Already added.
#if Matrix_Diagnostics
                        InstanceMonitor.Error("Message bus client [" + clientId.ToString() + "] added more than once.");
#endif
                        return(ClientId.InvalidMessageBusClientIndex);
                    }

                    // Add the client to a new spot.
                    _clientsHotSwap.Add(client);
                    index = _clientsHotSwap.Count - 1;
                }


                // This type of assignment will also work with multiple entries.
                // This performs an internal hotswap.
                _guidToIndexHotSwap[clientId.Guid] = index;
            }

            if (client != null &&
                client.AssignMessageBus(this, index) == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("A client has denied adding to Message bus.");
#endif
                RemoveClient(client, true);
                return(ClientId.InvalidMessageBusClientIndex);
            }

            client.UpdateEvent += new MessageBusClient.ClientUpdateDelegate(client_UpdateEvent);

            RaiseClientAddedEvent(clientId);

            return(index);
        }
예제 #11
0
 public abstract bool AddClient(MessageBusClient client);
예제 #12
0
 public abstract bool RemoveClient(MessageBusClient client, bool isPermanent);
예제 #13
0
 public abstract bool AddClient(MessageBusClient client);
예제 #14
0
 public abstract bool RemoveClient(MessageBusClient client, bool isPermanent);
예제 #15
0
        protected override void client_UpdateEvent(MessageBusClient client)
        {
            base.client_UpdateEvent(client);

            // Also send this notification to clients.
            int[] keys;
            lock (_syncRoot)
            {
                keys = GeneralHelper.EnumerableToArray<int>(_remoteClientsNetIds.Keys);
            }

            ClientUpdateMessage message = new ClientUpdateMessage() {
                                                                        ClientId = client.Id, MessageId = PendingMessageId, RequestResponse = false };

            foreach (int key in keys)
            {
                ToClient(key, message, null);
            }
        }
예제 #16
0
        /// <summary>
        /// Remove a client from the bus.
        /// </summary>
        public override bool RemoveClient(MessageBusClient client, bool isPermanent)
        {
            int id = client.Id.LocalMessageBusIndex;

            lock (_syncRoot)
            {
                if (_clientsHotSwap.Count <= id || id < 0)
                {
            #if Matrix_Diagnostics
                    SystemMonitor.OperationError("Failed to remove client from message bus.");
            #endif
                    return false;
                }

                if (_clientsHotSwap[id] != client)
                {
            #if Matrix_Diagnostics
                    SystemMonitor.OperationError("Client [" + client.Id.ToString() + "] not removed, since it does not belong to this message bus with this ID.");
            #endif
                    return false;
                }

                // Performs an internal hot swap.
                _clientsHotSwap[id] = null;

                // Performs an internal hot swap.
                _guidToIndexHotSwap[client.Id.Guid] = ClientId.InvalidMessageBusClientIndex;
            }

            client.UpdateEvent -= new MessageBusClient.ClientUpdateDelegate(client_UpdateEvent);
            client.ReleaseMessageBus();

            RaiseClientRemovedEvent(client.Id, isPermanent);

            return true;
        }
예제 #17
0
        /// <summary>
        /// Add a client to the message bus.
        /// </summary>
        public override bool AddClient(MessageBusClient client)
        {
            if (client == null)
            {
                return false;
            }

            if (client.ExecutionStrategy == null)
            {// Assign the client an instance of the default type of execution strategy used.
                client.SetupExecutionStrategy(new ThreadPoolFastExecutionStrategy(true));
            }

            if (DoAddClient(client, client.Id) == ClientId.InvalidMessageBusClientIndex)
            {
                return false;
            }

            return true;
        }
예제 #18
0
        /// <summary>
        /// Needs to consume both client and id, since it may be used with client == null.
        /// </summary>
        /// <returns>The index of the newly registered client, or InvalidClientIndex on failure.</returns>
        protected int DoAddClient(MessageBusClient client, ClientId clientId)
        {
            int index = 0;

            if (client != null && client.Id.Equals(clientId) == false)
            {
            #if Matrix_Diagnostics
                InstanceMonitor.Error("Client id mismatch.");
            #endif
                return ClientId.InvalidMessageBusClientIndex;
            }

            lock (_syncRoot)
            {
                if (clientId.LocalMessageBusIndex != ClientId.InvalidMessageBusClientIndex)
                {// Client already has an Index assigned, must reuse it.

                    MessageBusClient existingInstance = null;
                    if (_clientsHotSwap.TryGetValue(clientId.LocalMessageBusIndex, ref existingInstance))
                    {// Successfully acquired existing value for client.

                        // Check if we are OK to assign to this position.
                        if (existingInstance != null && existingInstance != client)
                        {// There is something else at that position.
            #if Matrix_Diagnostics
                            InstanceMonitor.Error("Client id mismatch.");
            #endif
                            return ClientId.InvalidMessageBusClientIndex;
                        }

                    }
                    else
                    {// Failed to acquire value with this message bus index.
            #if Matrix_Diagnostics
                        InstanceMonitor.Error("Client with this message bus index can not be assigned.");
            #endif
                        return ClientId.InvalidMessageBusClientIndex;
                    }

                    // Assign the client to its former spot.
                    _clientsHotSwap[clientId.LocalMessageBusIndex] = client;
                    index = clientId.LocalMessageBusIndex;
                }
                else
                {
                    if (GetClientIndexByGuid(clientId.Guid) >= 0)
                    {// Already added.
            #if Matrix_Diagnostics
                        InstanceMonitor.Error("Message bus client [" + clientId.ToString() + "] added more than once.");
            #endif
                        return ClientId.InvalidMessageBusClientIndex;
                    }

                    // Add the client to a new spot.
                    _clientsHotSwap.Add(client);
                    index = _clientsHotSwap.Count - 1;
                }

                // This type of assignment will also work with multiple entries.
                // This performs an internal hotswap.
                _guidToIndexHotSwap[clientId.Guid] = index;
            }

            if (client != null &&
                client.AssignMessageBus(this, index) == false)
            {
            #if Matrix_Diagnostics
                InstanceMonitor.OperationError("A client has denied adding to Message bus.");
            #endif
                RemoveClient(client, true);
                return ClientId.InvalidMessageBusClientIndex;
            }

            client.UpdateEvent += new MessageBusClient.ClientUpdateDelegate(client_UpdateEvent);

            RaiseClientAddedEvent(clientId);

            return index;
        }
예제 #19
0
        protected override void client_UpdateEvent(MessageBusClient client)
        {
            base.client_UpdateEvent(client);

            // Also send this notification to server.
            ToServer(new ClientUpdateMessage() { ClientId = client.Id, MessageId = PendingMessageId, RequestResponse = false }, null);
        }