Пример #1
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public SocketMessageServer(ISerializer serializer)
 {
     #if Matrix_Diagnostics
     _monitor = new InstanceMonitor(this);
     #endif
     _serializer = serializer;
 }
Пример #2
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public SuperPoolClients()
 {
     #if Matrix_Diagnostics
     InstanceMonitor = new InstanceMonitor(this);
     #endif
     _proxyTypeManager = new ProxyTypeManager();
 }
Пример #3
0
        /// <summary>
        /// Constructor, when socket already connected.
        /// </summary>
        /// <param name="messageSerializer"></param>
        /// <param name="socket"></param>
        public SocketCommunicator(ISerializer serializer)
        {
            #if Matrix_Diagnostics
            _monitor = new InstanceMonitor(this);
            Monitor.Info("Socket communicator created.");
            #endif

            _serializer = serializer;
        }
Пример #4
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public MessageBusBase(string name)
        {
            _name = name;

            #if Matrix_Diagnostics
            _monitor = new InstanceMonitor(this);
            #endif

            _defaultThreadPool = new ThreadPoolFastEx(name + ".DefaultThreadPool");

            _defaultThreadPool.MinimumThreadsCount = 5;
            _defaultThreadPool.MaximumThreadsCount = 10;
        }
Пример #5
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public ThreadPoolFast(string name)
        {
            #if Matrix_Diagnostics
            _monitor = new InstanceMonitor(this);
            #endif

            _name = name;
            ApplicationLifetimeHelper.ApplicationClosingEvent += new GeneralHelper.DefaultDelegate(GeneralHelper_ApplicationClosingEvent);

            _queueProcessorThread = new Thread(new ThreadStart(QueueProcessor));
            _queueProcessorThread.Name = name + ".QueueProcessor";
            _queueProcessorThread.Start();
        }
Пример #6
0
        /// <summary>
        /// Attach object to a new socket.
        /// </summary>
        /// <param name="socket"></param>
        /// <returns></returns>
        public void AssignSocket(System.Net.Sockets.Socket socket, bool disposeCurrentSocket)
        {
#if Matrix_Diagnostics
            InstanceMonitor monitor = Monitor;
            if (monitor != null && monitor.IsReportAllowed)
            {
                monitor.Info(string.Format("Socket assigned, disposing current [{0}].", disposeCurrentSocket));
            }
#endif

            ReleaseSocket(disposeCurrentSocket);
            lock (_syncRoot)
            {
                _socket = socket;
            }

            AssignAsyncReceiveArgs(true);
        }
Пример #7
0
        void ReleaseAsyncReceiveArgs()
        {
#if Matrix_Diagnostics
            InstanceMonitor monitor = Monitor;
            if (monitor != null && monitor.IsReportAllowed)
            {
                monitor.Info("Releasing async receive arguments.");
            }
#endif

            lock (_syncRoot)
            {
                if (_lastReceiveArgs != null)
                {// Release the existing receive args.
                    _lastReceiveArgs.Completed -= new EventHandler <SocketAsyncEventArgs>(SocketAsyncEventArgs_Received);
                    _lastReceiveArgs.Dispose();
                    _lastReceiveArgs = null;
                }
            }
        }
        /// <summary>
        /// Initializes all routing instance from the configuration in the configuration file.
        /// </summary>
        public static void BootFromConfiguration()
        {
            // register vehicle profiles.
            Vehicle.RegisterVehicles();

            // enable logging and use the console as output.
            OsmSharp.Logging.Log.Enable();
            OsmSharp.Logging.Log.RegisterListener(
                new OsmSharp.WinForms.UI.Logging.ConsoleTraceListener());
#if DEBUG
            OsmSharp.Logging.Log.RegisterListener(
                new Logging.DebugTraceListener());
#endif

            // get the api configuration.
            var apiConfiguration = (ApiConfiguration)ConfigurationManager.GetSection("ApiConfiguration");

            // load all relevant routers.
            foreach (InstanceConfiguration instanceConfiguration in apiConfiguration.Instances)
            {
                var thread = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
                {
                    // load instance.
                    if (LoadInstance(apiConfiguration, instanceConfiguration))
                    { // instance loaded correctly.
                        // start monitoring files...
                        if (instanceConfiguration.Monitor)
                        { // ...but only when configured as such.
                            var monitor = new InstanceMonitor(apiConfiguration, instanceConfiguration, LoadInstance);
                            _instanceMonitors.Add(monitor);

                            // get graph configuration.
                            var graph = instanceConfiguration.Graph;
                            monitor.AddFile(graph);
                            monitor.Start();
                        }
                    }
                }));
                thread.Start();
            }
        }
Пример #9
0
        /// <summary>
        /// Release the currently used socket.
        /// </summary>
        public void ReleaseSocket(bool disposeSocket)
        {
#if Matrix_Diagnostics
            InstanceMonitor monitor = Monitor;
            if (monitor != null && monitor.IsReportAllowed)
            {
                monitor.Info(string.Format("Releasing socket, dipose [{0}].", disposeSocket));
            }
#endif

            lock (_syncRoot)
            {
                System.Net.Sockets.Socket socket = _socket;
                if (socket != null && disposeSocket)
                {
                    socket.Disconnect(false);
                    socket.Close();
                }
                _socket = null;
            }
        }
Пример #10
0
        internal override void ProcessSystemMessage(SystemMessage message)
        {// Received a system message.
#if Matrix_Diagnostics
            InstanceMonitor monitor = Monitor;
            if (monitor != null && monitor.IsReportAllowed)
            {
                monitor.Info(string.Format("Processing system message [{0}].", message.ToString()));
            }
#endif

            if (message.Type == SystemMessage.TypeEnum.KeepAlive &&
                this.KeepAlive == false)
            {// Make sure to activate keep alive on this side too.
#if Matrix_Diagnostics
                monitor.Warning("Received KeepAlive, and KeepAlive not active on this client, auto-activating.");
#endif
                this.KeepAlive = true;
            }

            _lastMessageReceivedTime = DateTime.Now;
        }
Пример #11
0
        protected virtual bool HandleClientRemoved(IMessageBus messageBus, ClientId clientId, bool isPermanent)
        {
            Type clientType = messageBus.GetClientType(clientId);

            if (clientType == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to establish client type.");
#endif
                return(false);
            }

            if (clientType != typeof(SuperPoolClient) &&
                clientType.IsSubclassOf(typeof(SuperPoolClient)) == false)
            {// Client not a super pool client.
                return(false);
            }

            UnRegisterClientSourceTypes(clientId);

            return(true);
        }
Пример #12
0
        /// <summary>
        /// Initialize the pool for operation, by supplying it with a message bus.
        /// </summary>
        protected virtual bool Initialize(IMessageBus messageBus)
        {
            lock (this)
            {
                if (_messageBus != null || messageBus == null)
                {
                    return(false);
                }

                _messageBus = messageBus;
                _messageBus.ClientAddedEvent   += new MessageBusClientUpdateDelegate(_messageBus_ClientAddedEvent);
                _messageBus.ClientRemovedEvent += new MessageBusClientRemovedDelegate(_messageBus_ClientRemovedEvent);
                _messageBus.ClientUpdateEvent  += new MessageBusClientUpdateDelegate(_messageBus_ClientUpdateEvent);

                // Add a client with self to the message bus.
                IntercomClient = new SuperPoolClient("SuperPool.Intercom", this);
            }

            if (this.AddClient(IntercomClient) == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Fatal("Failed to add super pool main client.");
#endif
                lock (this)
                {
                    IntercomClient.Dispose();
                    IntercomClient = null;

                    _messageBus.ClientAddedEvent   -= new MessageBusClientUpdateDelegate(_messageBus_ClientAddedEvent);
                    _messageBus.ClientRemovedEvent -= new MessageBusClientRemovedDelegate(_messageBus_ClientRemovedEvent);
                    _messageBus.ClientUpdateEvent  -= new MessageBusClientUpdateDelegate(_messageBus_ClientUpdateEvent);
                    _messageBus = null;
                }

                return(false);
            }

            return(true);
        }
Пример #13
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);
        }
        /// <summary>
        /// Does the actual bootstrapping.
        /// </summary>
        public static void BootFromConfiguration()
        {
            // get the api configuration.
            var apiConfiguration = (TileApiConfiguration)ConfigurationManager.GetSection("TileApiConfiguration");

            // load all relevant routers.
            foreach (InstanceConfiguration instanceConfiguration in apiConfiguration.Instances)
            {
                var thread = new System.Threading.Thread(new System.Threading.ThreadStart(() =>
                {
                    // load instance.
                    if (LoadInstance(apiConfiguration, instanceConfiguration))
                    { // instance loaded correctly.
                        // start monitoring files...
                        if (apiConfiguration.Monitor)
                        { // ...but only when configured as such.
                            var monitor = new InstanceMonitor(apiConfiguration, instanceConfiguration, LoadInstance);
                            _instanceMonitors.Add(monitor);

                            // get data file configuration.
                            var data = instanceConfiguration.Data;
                            if (!string.IsNullOrWhiteSpace(data))
                            { // monitor data.
                                monitor.AddFile(data);
                            }
                            // get mapcss configuration.
                            var mapCSS = instanceConfiguration.MapCSS;
                            if (!string.IsNullOrWhiteSpace(mapCSS))
                            { // monitor mapcss.
                                monitor.AddFile(mapCSS);
                            }
                            monitor.Start();
                        }
                    }
                }));
                thread.Start();
            }
        }
Пример #15
0
        /// <summary>
        /// Process an event call.
        /// </summary>
        void ProcessEventCall(ClientId senderId, ClientId receiverId,
                              MethodInfo targetMethodInfo, object[] parameters)
        {
            if (receiverId == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Error("Proxy call receiver not received.");
#endif
                return;
            }

            IMessageBus messageBus = MessageBus;
            if (messageBus == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find message bus (possible dispose).");
#endif
                return;
            }

            SuperPoolCall call = new SuperPoolCall(GetUniqueCallId());

            call.Parameters      = parameters;
            call.MethodInfoLocal = targetMethodInfo;

            call.State = SuperPoolCall.StateEnum.EventRaise;

            if (messageBus.Send(senderId, receiverId,
                                new Envelope(call)
            {
                DuplicationMode = Envelope.DuplicationModeEnum.None
            }, null, false) != Outcomes.Success)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to send event proxy call.");
#endif
            }
        }
Пример #16
0
        /// <summary>
        /// Disconnect was completed.
        /// </summary>
        void SocketAsyncEventArgs_DisconnectComplete(object sender, SocketAsyncEventArgs e)
        {
#if Matrix_Diagnostics
            InstanceMonitor monitor = Monitor;
            if (monitor != null && monitor.IsReportAllowed)
            {
                monitor.Info("Disconnecting completed.");
            }
#endif

            if (e.SocketError == SocketError.Success)
            {
                e.Completed -= new EventHandler <SocketAsyncEventArgs>(SocketAsyncEventArgs_DisconnectComplete);
                e.Dispose();

#if Matrix_Diagnostics
                Monitor.ReportImportant("Disconnected.");
#endif
                RaiseDisconnectedEvent();
            }

            ReleaseAsyncReceiveArgs();
        }
Пример #17
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);
        }
Пример #18
0
        void _messageClient_MessageReceivedEvent(SocketCommunicator helper, object message)
        {
            if (message is EnvelopeMessage)
            {
                EnvelopeMessage envelopeMessage = (EnvelopeMessage)message;

                // Remove the remote message bus index association.
                envelopeMessage.Sender.LocalMessageBusIndex = ClientId.InvalidMessageBusClientIndex;

                foreach (ClientId id in envelopeMessage.Receivers)
                {
                    // Decode the id.
                    id.LocalMessageBusIndex = base.GetClientIndexByGuid(id.Guid);

                    if (id.IsMessageBusIndexValid)
                    {
                        // Assign as a part of the local bus.
                        id.MessageBus = this;
                        if (DoSendToClient(envelopeMessage.Sender, id, envelopeMessage.Envelope, null) != SendToClientResultEnum.Success)
                        {
#if Matrix_Diagnostics
                            InstanceMonitor.OperationError(string.Format("Failed to accept envelope message [{0}].", envelopeMessage.ToString()));
#endif
                        }
                    }
                    else
                    {
#if Matrix_Diagnostics
                        InstanceMonitor.OperationError(string.Format("Failed to accept envelope message [{0}] due to unrecognized receiver id.", envelopeMessage.ToString()));
#endif
                    }
                }
            }
            else if (message is ClientsListMessage)
            {// Received client update from server.
                ClientsListMessage listMessage = (ClientsListMessage)message;

                int jef = 0;
                foreach (var client in listMessage.Ids)
                {
                    Console.WriteLine("Incoming client id: " + client + " Source type: " + listMessage.SourcesTypes[jef]);
                    jef++;
                }

                List <ClientId> existingIds = new List <ClientId>();
                lock (_syncRoot)
                {
                    existingIds.AddRange(_originalServerClientsHotSwap.Values);

                    _originalServerClientsHotSwap.Clear();
                    _originalServerClientsTypesHotSwap.Clear();
                    _originalServerClientsSourcesTypesHotNamesSwap.Clear();

                    // Preprocess Ids, by assigning them new indeces and adding to the local message bus register.
                    for (int i = 0; i < listMessage.Ids.Count; i++)
                    {
                        // Add an original copy to the list.
                        _originalServerClientsHotSwap.Add(listMessage.Ids[i].Guid, listMessage.Ids[i]);

                        _originalServerClientsTypesHotSwap.Add(listMessage.Ids[i].Guid, listMessage.Types[i]);
                        _originalServerClientsSourcesTypesHotNamesSwap.Add(listMessage.Ids[i].Guid, listMessage.SourcesTypes[i]);

                        // Add the client to a new spot.
                        //_clientsHotSwap.Add(null);
                        //int messageBusIndex = _clientsHotSwap.Count - 1;

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

                        // Also add to this classes collection.
                        //_localToRemoteId[messageBusIndex] = id;
                    }
                }

                foreach (ClientId id in listMessage.Ids)
                {
                    existingIds.Remove(id);
                    RaiseClientAddedEvent(id);
                }

                // Raise for any that were removed.
                foreach (ClientId id in existingIds)
                {
                    RaiseClientRemovedEvent(id, true);
                }
            }
            else if (message is RequestClientListUpdateMessage)
            {
                SendClientsUpdate();
            }
            else if (message is ClientUpdateMessage)
            {
                ClientUpdateMessage updateMessage = (ClientUpdateMessage)message;

                if (_originalServerClientsHotSwap.ContainsKey(updateMessage.ClientId.Guid))
                {
                    RaiseClientUpdateEvent(updateMessage.ClientId);
                }
                else
                {
#if Matrix_Diagnostics
                    InstanceMonitor.OperationError(string.Format("Failed to raise update event for client [{0}], since client not found.", updateMessage.ClientId.ToString()));
#endif
                }
            }
            else if (message is StateUpdateMessage)
            {
                RaiseCounterPartyUpdateEvent("Server", ((StateUpdateMessage)message).State.ToString());
            }
            else
            {
#if Matrix_Diagnostics
                InstanceMonitor.Warning(string.Format("Message [{0}] not recognized.", message.GetType().Name));
#endif
            }
        }
Пример #19
0
        void ISuperPoolIntercom.ProcessSubscriptionUpdate(EventSubscriptionRequest subscriptionRequest)
        {
            // Filter request, since it may not be related at all to this super pool.
            bool clientFound = false;
            ReadOnlyCollection <ClientId> sources = subscriptionRequest.EventsSources;

            if (sources == null)
            {// Null value indicates a subscirption to all possible sources.
                clientFound = true;
            }
            else
            {
                foreach (ClientId id in sources)
                {
                    if (_clients.ContainsKey(id))
                    {
                        clientFound = true;
                        break;
                    }
                }
            }

            // Check the sources and the SenderId, before dumping event.
            if (clientFound == false && subscriptionRequest.SenderId.IsLocalClientId == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Info("Subscription request received [" + subscriptionRequest.ToString() + "], ignored since not related.");
#endif
                return;
            }
            else
            {
#if Matrix_Diagnostics
                InstanceMonitor.Info("Subscription request received [" + subscriptionRequest.ToString() + "] and processing...");
#endif
            }

            EventSubscriptionInfo methodSubscription = null;
            if (_eventSubscriptions.TryGetValue(subscriptionRequest.ExtendedEventName, out methodSubscription) == false)
            {
                lock (_syncRoot)
                {
                    if (_eventSubscriptions.TryGetValue(subscriptionRequest.ExtendedEventName, out methodSubscription) == false)
                    {// Add a new method subscription info.
                        methodSubscription = new EventSubscriptionInfo(subscriptionRequest.ExtendedEventName);
                        _eventSubscriptions.Add(subscriptionRequest.ExtendedEventName, methodSubscription);
                    }
                }
            }

            if (methodSubscription == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find method subscription, subscription failed.");
#endif
                return;
            }

            // Apply the requests locally.
            methodSubscription.SubscriptionUpdate(subscriptionRequest);
        }
Пример #20
0
        /// <summary>
        /// Send a message, asynchronously.
        /// </summary>
        /// <param name="message">The message being sent.</param>
        /// <param name="requestConfirm">Should we wait for a confirmation, the </param>
        /// <returns>The id of the send message, or negative value (InvalidSendIndex / -1) if send failed.</returns>
        public long SendAsync(object message, TimeSpan?requestConfirmTimeout)
        {
#if Matrix_Diagnostics
            InstanceMonitor monitor = Monitor;
            if (monitor != null && monitor.IsReportAllowed)
            {
                monitor.Info(string.Format("Async sending message [{0}].", message.ToString()));
            }
#endif

            System.Net.Sockets.Socket socket = _socket;
            if (IsConnected == false || socket == null)
            {
#if Matrix_Diagnostics
                Monitor.OperationError("Communicator can not send message [" + message.ToString() + "] since not connected.");
#endif
                return(InvalidSendIndex);
            }

            ISerializer serializer = _serializer;
            if (serializer == null)
            {
                return(InvalidSendIndex);
            }

            // Event used for confirmed calls
            ManualResetEvent sendCompleteEvent = null;
            if (requestConfirmTimeout.HasValue)
            {
                sendCompleteEvent = new ManualResetEvent(false);
            }

            AsyncMessageSendInfo messageSendInfo = new AsyncMessageSendInfo()
            {
                Id                = PendingSendId,
                Socket            = socket,
                Message           = message,
                ConfirmationEvent = sendCompleteEvent,
            };

            SocketAsyncEventArgs e = new SocketAsyncEventArgs();
            e.UserToken  = messageSendInfo;
            e.Completed += new EventHandler <SocketAsyncEventArgs>(SocketAsyncEventArgs_SendComplete);

            messageSendInfo.Stream = new MemoryStream();
            if (serializer.Serialize(messageSendInfo.Stream, message) == false)
            {
                messageSendInfo.Dispose();
                return(InvalidSendIndex);
            }

            e.SetBuffer(messageSendInfo.Stream.GetBuffer(), 0, (int)messageSendInfo.Stream.Length);
            if (messageSendInfo.Socket.SendAsync(e) == false)
            {
                messageSendInfo.Dispose();
            }

            // Reaquire the event, to lessen the chance of [ObjectDisposedException]
            // when the connection is not established and we get errors on complete instantly.
            sendCompleteEvent = messageSendInfo.ConfirmationEvent;
            if (sendCompleteEvent != null)
            {
                try
                {
                    if (sendCompleteEvent.WaitOne(requestConfirmTimeout.Value) == false)
                    {
#if Matrix_Diagnostics
                        Monitor.OperationError("Communicator could not confirm message sent in assigned timeout.");
#endif
                        return(InvalidSendIndex);
                    }
                }
                catch (ObjectDisposedException)
                {
#if Matrix_Diagnostics
                    Monitor.OperationError("Communicator could not confirm message sent in assigned timeout, due to event disposed.");
#endif
                    return(InvalidSendIndex);
                }
            }

            return(messageSendInfo.Id);
        }
Пример #21
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);
        }
Пример #22
0
        void _server_ClientMessageReceivedEvent(SocketMessageServer server, SocketCommunicatorEx client, object message)
        {
            ServerAccessControl accessControl = AccessControl;

            // Check security first.
            if (accessControl != null && message is AccessMessage == false)
            {
                if (accessControl.IsAllowed(ObtainClientAccessControl(client.Id)) == false)
                {
#if Matrix_Diagnostics
                    InstanceMonitor.Info("Message [" + message.ToString() + "] from client [" + client.ToString() + "] not allowed due to access control.", TracerItem.PriorityEnum.Medium);
#endif
                    return;
                }
            }

            if (message is EnvelopeMessage)
            {// Envelope user message.
                EnvelopeMessage envelopeMessage = (EnvelopeMessage)message;

                // Remove the remote message bus index association.
                envelopeMessage.Sender.LocalMessageBusIndex = ClientId.InvalidMessageBusClientIndex;

                foreach (ClientId id in envelopeMessage.Receivers)
                {
                    // Assign the id as local id, if it is, otherwise skip it.
                    id.LocalMessageBusIndex = base.GetClientIndexByGuid(id.Guid);
                    if (id.IsMessageBusIndexValid)
                    {
                        id.MessageBus = this;
                        if (DoSendToClient(envelopeMessage.Sender, id, envelopeMessage.Envelope, null) != SendToClientResultEnum.Success)
                        {
#if Matrix_Diagnostics
                            InstanceMonitor.OperationError(string.Format("Failed to accept envelope message [{0}].", envelopeMessage.ToString()));
#endif
                        }
                    }
                    else
                    {
#if Matrix_Diagnostics
                        InstanceMonitor.OperationError(string.Format("Failed to accept envelope message [{0}] due unrecognized receiver id.", envelopeMessage.ToString()));
#endif
                    }
                }
            }
            else if (message is ClientsListMessage)
            {// Message bus system message.
                ClientsListMessage updateMessage = (ClientsListMessage)message;
                for (int i = 0; i < updateMessage.Ids.Count; i++)
                {
                    RegisterClientId(client.Id, updateMessage.Ids[i], updateMessage.Types[i], updateMessage.SourcesTypes[i]);
                }
            }
            else if (message is RequestClientListUpdateMessage)
            {
                SendClientsUpdate(client.Id);
            }
            else if (message is ClientUpdateMessage)
            {
                ClientUpdateMessage updateMessage = (ClientUpdateMessage)message;

                bool validClient;
                lock (_syncRoot)
                {
                    validClient = _remoteClientNetId.ContainsKey(updateMessage.ClientId);
                }

                if (validClient)
                {
                    RaiseClientAddedEvent(updateMessage.ClientId);
                }
                else
                {
#if Matrix_Diagnostics
                    InstanceMonitor.OperationError(string.Format("Failed to raise update event for client [{0}], since client not found.", updateMessage.ClientId.ToString()));
#endif
                }
            }
            else if (message is AccessMessage)
            {
                ClientAccessControl control = ObtainClientAccessControl(client.Id);
                if (control != null)
                {
                    control.Update(message as AccessMessage);
                }
            }
            else if (message is StateUpdateMessage)
            {
                RaiseCounterPartyUpdateEvent("Client:" + client.Id.ToString(), ((StateUpdateMessage)message).State.ToString());
            }
            else
            {
#if Matrix_Diagnostics
                InstanceMonitor.Warning(string.Format("Message [{0}] not recognized.", message.GetType().Name));
#endif
            }
        }
Пример #23
0
        /// <summary>
        /// Handle event subscription (Proxy.Event.Subscribe)
        /// </summary>
        protected override void ProcessReceiveEventSubscription(int methodId, Delegate delegateInstance, bool isAdd)
        {
            SuperPoolProxyCall pendingCall = null;

            if (_pendingThreadsCalls.TryGetValue(Thread.CurrentThread.ManagedThreadId, out pendingCall) == false)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find corresponding thread proxy call information.");
#endif
                return;
            }

            EventSubscriptionRequest subscriptionRequest = pendingCall.SubscriptionRequest;
            if (subscriptionRequest == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find corresponding subscription requests, event subscription failed.");
#endif
                return;
            }

            if (pendingCall.Sender == null || pendingCall.Sender.Id == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to establish subscription sender information, subscription failed.");
#endif
                return;
            }

            if (delegateInstance.Target != pendingCall.Sender.Source)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Error("Only a message super pool client source can subscribe to events.");
#endif
                return;
            }

            ProxyTypeBuilder builder = ProxyTypeBuilder;
            if (builder == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find proxy type builder, event subscription failed.");
#endif
                return;
            }

            GeneratedMethodInfo generatedMethodInfo = builder.GetMethodInfoById(methodId);
            if (generatedMethodInfo == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.OperationError("Failed to find method [id, " + methodId + "] info, event subscription failed.");
#endif
                return;
            }

            if (string.IsNullOrEmpty(generatedMethodInfo.EventName))
            {
                generatedMethodInfo.EventName = GeneralHelper.GetEventExtendedNameByMethod(generatedMethodInfo.GetMethodInfo(), false, true);
            }

            // generatedMethodInfo.GetMethodInfo() >> I2.add_AEVent
            string     extendedEventName  = generatedMethodInfo.EventName;
            MethodInfo eventAddMethodInfo = generatedMethodInfo.GetMethodInfo();

            // *IMPORTANT* the Call<> will cause the currently used pendingCall to be repopulated with information,
            // so we ned to extract the *sender id* BEFORE calling the actual Call(), since it will change the
            // pendingCall instance immediately.
            subscriptionRequest.SenderId          = pendingCall.Sender.Id;
            subscriptionRequest.ExtendedEventName = extendedEventName;
            subscriptionRequest.IsAdd             = isAdd;
            //subscriptionRequest.EventAddMethodInfo = eventAddMethodInfo;
            subscriptionRequest.DelegateInstanceMethodInfo = delegateInstance.Method;

            // Process locally.
            ((ISuperPoolIntercom)this).ProcessSubscriptionUpdate(subscriptionRequest);

            SuperPoolClient mainClient = IntercomClient;
            if (mainClient == null)
            {
#if Matrix_Diagnostics
                InstanceMonitor.Error("Failed to obtain super pool main intercom client, so new client handling has failed.");
#endif
            }
            else
            {
                // 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*
                mainClient.CallAll <ISuperPoolIntercom>().ProcessSubscriptionUpdate(subscriptionRequest);
            }
        }