public bool DisconnectClient(int clientId) { SocketCommunicatorEx client; if (_clientsHotSwap.TryGetValue(clientId, out client) == false) { return(false); } return(client.DisconnectAsync()); }
/// <summary> /// Obtain a collection of the Ids of all clients that implement the interface. /// </summary> /// <param name="interfaceType"></param> /// <returns>The actual hot swap instance, of the collection with the interfaces, thus making it an ultra-fast (instant) result.</returns> public ClientId GetFirstInterfaceImplementor(Type interfaceType) { HotSwapList <ClientId> result = null; if (_clientsInterfaces.TryGetValue(interfaceType, out result) == false) { return(null); } if (result.Count > 0) { return(result[0]); } return(null); }
/// <summary> /// Will return negative value (for ex. -1, or see InvalidClientIndex) to indicate not found. /// </summary> /// <param name="id"></param> /// <returns></returns> protected int GetClientIndexByGuid(Guid guid) { int result = 0; if (_guidToIndexHotSwap.TryGetValue(guid, out result) == false) { return(ClientId.InvalidMessageBusClientIndex); } return(result); }
/// <summary> /// Obtain a list of the receivers of the event raise. /// </summary> /// <param name="specific">True to get the specific for this one, false to get the "subscribe to all"</param> public HotSwapDictionary <ClientId, ClientEventSubscriptionInfo> GetReceivers(ClientId sourceId, bool specific) { HotSwapDictionary <ClientId, ClientEventSubscriptionInfo> result; if (specific) { if (_subscriptionsHotSwap.TryGetValue(sourceId, out result) == false) {// If not found, return an empty one. result = new HotSwapDictionary <ClientId, ClientEventSubscriptionInfo>(); } } else { if (_subscriptionsHotSwap.TryGetValue(SubscribeToAllId, out result) == false) {// If not found, return an empty one. result = new HotSwapDictionary <ClientId, ClientEventSubscriptionInfo>(); } } return(result); }
public override List <string> GetClientSourceTypes(ClientId clientId) { if (clientId.IsMessageBusIndexValid && clientId.MessageBus == this) {// Seems to be a local client Id. return(base.GetClientSourceTypes(clientId)); } List <string> names; if (_originalServerClientsSourcesTypesHotNamesSwap.TryGetValue(clientId.Guid, out names)) { return(names); } return(null); }
public override Type GetClientType(ClientId clientId) { if (clientId.IsMessageBusIndexValid && clientId.MessageBus == this) {// Seems to be a local client Id. return(base.GetClientType(clientId)); } Type value; if (_originalServerClientsTypesHotSwap.TryGetValue(clientId.Guid, out value)) { return(value); } return(null); }
/// <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); }
/// <summary> /// An event (with return value) was raised by our source. /// </summary> public object ReceiveDynamicMethodCallAndReturn(int methodId, Type returnType, object[] parameters) { EventHandlingInformation eventSubscriptionInfo; if (_eventsMethods.TryGetValue(methodId, out eventSubscriptionInfo) == false) { #if Matrix_Diagnostics SystemMonitor.OperationError("Failed to find corresponding method info, invocation aborted (possible dispose)."); #endif return(ProxyTypeManager.GetTypeDefaultValue(returnType)); } SuperPoolSubscription owner = _owner; if (owner == null) { #if Matrix_Diagnostics SystemMonitor.OperationError("Owner not assign, invocation aborted (possible dispose)."); #endif return(ProxyTypeManager.GetTypeDefaultValue(returnType)); } return(owner.ProcessEventRaised(this, eventSubscriptionInfo, returnType, parameters)); }
/// <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); }
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); }