/// <summary> /// Constructor. /// </summary> public SocketMessageServer(ISerializer serializer) { #if Matrix_Diagnostics _monitor = new InstanceMonitor(this); #endif _serializer = serializer; }
/// <summary> /// Constructor. /// </summary> public SuperPoolClients() { #if Matrix_Diagnostics InstanceMonitor = new InstanceMonitor(this); #endif _proxyTypeManager = new ProxyTypeManager(); }
/// <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; }
/// <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; }
/// <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(); }
/// <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); }
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(); } }
/// <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; } }
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; }
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); }
/// <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); }
/// <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(); } }
/// <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 } }
/// <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(); }
/// <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); }
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 } }
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); }
/// <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); }
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); }
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 } }
/// <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); } }