void IProxyTypeSink.ReceivePropertySet(int methodId, object value) { 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; } pendingCall.Parameters = new object[] { value }; pendingCall.ReturnType = null; ProxyTypeBuilder builder = ProxyTypeBuilder; if (builder == null) { #if Matrix_Diagnostics InstanceMonitor.OperationError("Failed to find proxy type builder."); #endif return; } pendingCall.MethodInfo = builder.GetMethodInfoById(methodId); if (pendingCall.MethodInfo == null) { #if Matrix_Diagnostics InstanceMonitor.OperationError("Failed to find method [" + methodId + "] info."); #endif return; } pendingCall.Sender.ProcessCall(pendingCall); }
/// <summary> /// Process a pool call. /// </summary> object ProcessReceiveCall(int methodId, Type returnType, object[] parameters) { 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(null); } pendingCall.Parameters = parameters; pendingCall.ReturnType = returnType; ProxyTypeBuilder builder = ProxyTypeBuilder; if (builder == null) { #if Matrix_Diagnostics InstanceMonitor.OperationError("Failed to find proxy type builder."); #endif return(ProxyTypeManager.GetTypeDefaultValue(returnType)); } pendingCall.MethodInfo = builder.GetMethodInfoById(methodId); if (pendingCall.MethodInfo == null) { #if Matrix_Diagnostics InstanceMonitor.OperationError("Failed to find method [" + methodId + "] info."); #endif return(ProxyTypeManager.GetTypeDefaultValue(returnType)); } return(pendingCall.Sender.ProcessCall(pendingCall)); }
void _server_ClientConnectedEvent(SocketMessageServer server, SocketCommunicatorEx client) { // The client expects is, so activate keep alive. client.KeepAlive = true; // Send local bus clients info to connected element. // Important - this will also be sent even to clients that do not have verified access control. if (SendClientsUpdate(client.Id) == false) { #if Matrix_Diagnostics InstanceMonitor.OperationError("Failed to send clients update to client [" + client.ToString() + ", " + client.Id + "]."); #endif } }
/// <summary> /// /// </summary> bool RegisterClientSourceTypes(ClientId clientId) { IMessageBus messageBus = _messageBus; if (messageBus == null) { Console.WriteLine("Failed to register client source type, message bus not found."); #if Matrix_Diagnostics InstanceMonitor.OperationError("Failed to register client source type, message bus not found."); #endif return(false); } List <string> sourceTypes = messageBus.GetClientSourceTypes(clientId); if (sourceTypes == null) { Console.WriteLine("Failed to register client source type, source type not found."); #if Matrix_Diagnostics InstanceMonitor.OperationError("Failed to register client source type, source type not found."); #endif return(false); } foreach (Type superType in ReflectionHelper.GetKnownTypes(sourceTypes)) { if (superType.IsInterface == false || ReflectionHelper.TypeHasCustomAttribute(superType, typeof(SuperPoolInterfaceAttribute), false) == false) { continue; } HotSwapList <ClientId> clientList = null; if (_clientsInterfaces.TryGetValue(superType, out clientList) == false) { clientList = _clientsInterfaces.GetOrAdd(superType, new HotSwapList <ClientId>()); } clientList.AddUnique(clientId); if (ReflectionHelper.TypeHasCustomAttribute(superType, typeof(SuperPoolInterfaceAttribute), false) == false) {// Register this type as well. _proxyTypeManager.ObtainInterfaceProxy(superType); } } return(true); }
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> /// 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> /// 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> /// 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 _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 } }
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> /// 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); } }