/// <summary> /// Client source has raised an event, process it. /// </summary> internal object ProcessEventRaised(ClientEventsHandler client, ClientEventsHandler.EventHandlingInformation eventSubscriptionInfo, Type returnType, object[] parameters) { if (string.IsNullOrEmpty(eventSubscriptionInfo.GeneratedMethodInfo.EventName)) { // Establish the name of the event. eventSubscriptionInfo.GeneratedMethodInfo.EventName = GeneralHelper.GetEventMethodExtendedName(eventSubscriptionInfo.EventInfo, false); } EventSubscriptionInfo eventSubscription = null; if (string.IsNullOrEmpty(eventSubscriptionInfo.GeneratedMethodInfo.EventName) == false && _eventSubscriptions.TryGetValue(eventSubscriptionInfo.GeneratedMethodInfo.EventName, out eventSubscription)) {// OK, to perform the calls. // Process specific subscribers foreach (KeyValuePair <ClientId, EventSubscriptionInfo.ClientEventSubscriptionInfo> pair in eventSubscription.GetReceivers(client.Client.Id, true)) { foreach (KeyValuePair <MethodInfo, int> subPair in pair.Value.Data) { for (int i = 0; i < subPair.Value; i++) { // May need to raise multiple times. if (client.Client.Id != pair.Key) { // Filter out subscriptions by the one that raised it. ProcessEventCall(client.Client.Id, pair.Key, subPair.Key, parameters); } } } } // Process subscribe to all. foreach (KeyValuePair <ClientId, EventSubscriptionInfo.ClientEventSubscriptionInfo> pair in eventSubscription.GetReceivers(client.Client.Id, false)) { foreach (KeyValuePair <MethodInfo, int> subPair in pair.Value.Data) { for (int i = 0; i < subPair.Value; i++) { // May need to raise multiple times. if (client.Client.Id != pair.Key) { // Filter out subscriptions by the one that raised it. ProcessEventCall(client.Client.Id, pair.Key, subPair.Key, parameters); } } } } } else {// No subscription(s) for this event. #if Matrix_Diagnostics InstanceMonitor.Info(string.Format("Event raised [{0}] had no subscribers.", eventSubscriptionInfo.GeneratedMethodInfo.EventName), TracerItem.PriorityEnum.Trivial); #endif } // Return a default value. return(ProxyTypeManager.GetTypeDefaultValue(returnType)); }
/// <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); }
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); }