/// <summary> /// Implementation, separate in order to allow calls from child classes. /// </summary> public static object GetTypeDefaultValue(Type returnType) { if (returnType == null || returnType.IsByRef || returnType.IsClass) { return(null); } object result; if (_defaultReturnValues.TryGetValue(returnType, out result)) { return(result); } result = Activator.CreateInstance(returnType); _defaultReturnValues.Add(returnType, result); return(result); }
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 } }
/// <summary> /// Basic asynchronous call operation. /// </summary> /// <param name="receiverId">The value of the receiver, null means call all.</param> internal bool Call <InterfaceType>(SuperPoolClient sender, IEnumerable <ComponentId> receiversIds, out InterfaceType result, out SuperPoolProxyCall call) where InterfaceType : class { call = null; result = null; // SLOW. //if (_messageBus.ContainsClient(sender.Id) == false) //{ // SystemMonitor.OperationError("Client not a member of message bus (and super pool)."); // return false; //} if (typeof(InterfaceType).IsInterface == false) { throw new Exception("Type provided not an interface."); } // Very slow !! //object[] attributes = typeof(InterfaceType).GetCustomAttributes(typeof(SuperPoolInterfaceAttribute), false); //if (attributes == null || attributes.Length == 0) //{ // SystemMonitor.Throw("Interface type [" + typeof(InterfaceType).Name + "] not marked as super pool interface."); // return false; //} ProxyTypeManager typeManager = _proxyTypeManager; if (typeManager == null) { return(false); } if (_pendingThreadsCalls.TryGetValue(Thread.CurrentThread.ManagedThreadId, out call) == false) {// We are safe from danger of someone else already adding the value with this id, // since we are the only thread with this id. call = new SuperPoolProxyCall(); // This is slow, but very rarely executed, since thread ids are reused. _pendingThreadsCalls.Add(Thread.CurrentThread.ManagedThreadId, call); } else { // Since we reuse the call, clean it up before usage. call.Clear(); } call.Processed = false; if (receiversIds != null) {// Extract the Indeces from the Ids. List <ClientId> receiversIndeces = new List <ClientId>(); foreach (ComponentId id in receiversIds) { receiversIndeces.Add((ClientId)id); } call.ReceiversIds = receiversIndeces; } else { call.ReceiversIds = null; } call.Sender = sender; result = (InterfaceType)typeManager.ObtainInterfaceProxy(typeof(InterfaceType)); return(true); }
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); }
protected void AssignClientSource(object source) { SuperPoolClient client = _client; if (client == null) { #if Matrix_Diagnostics SystemMonitor.Error("Failed to add client source, since client not available (possible Dispose)."); #endif return; } SuperPoolSubscription owner = _owner; if (owner == null) { #if Matrix_Diagnostics SystemMonitor.Error("Failed to add client source, since no owner is available (possible Dispose)."); #endif return; } ReleaseCurrentClientSource(); _clientSource = source; if (_clientSource == null) { #if Matrix_Diagnostics SystemMonitor.OperationWarning("Starting a client with no source attached."); #endif return; } foreach (Type interfaceType in ReflectionHelper.GatherTypeAttributeMarkedInterfaces(source.GetType(), typeof(SuperPoolInterfaceAttribute))) {// Gather all events, from interfaces marked with [SuperPoolInterfaceAttribute]. // Make sure to have created the corresponding proxy instance for this interface type. owner.ProxyTypeManager.ObtainInterfaceProxy(interfaceType); foreach (EventInfo eventInfo in interfaceType.GetEvents()) { Type delegateType = eventInfo.EventHandlerType; GeneratedMethodInfo methodInfo = owner.ProxyTypeManager.Builder.GenerateDynamicMethodProxyDelegate(delegateType); // Create delegate can operate in 2 modes: // - create a static delegate like this (requires instnace upon call): info.Method.CreateDelegate(delegateType); // - create an instance delegate like this (can be direct called): info.Method.CreateDelegate(delegateType, instance); Delegate delegateInstance = methodInfo.StandaloneDynamicMethod.CreateDelegate(delegateType, this); eventInfo.AddEventHandler(source, delegateInstance); EventHandlingInformation subscriptionInfo = new EventHandlingInformation() { DelegateInstance = delegateInstance, EventInfo = eventInfo, GeneratedMethodInfo = methodInfo }; lock (this) { _eventsMethods.Add(methodInfo.Id, subscriptionInfo); } } } }