/// <summary> /// Attaches an adapter to this switch. Starts the adapter if the switch is started. /// </summary> /// <param name="adapter">Adapter to be attached.</param> public void AddAdapter(IRemoteHubAdapter<byte[]> adapter) { var idList = new ConcurrentDictionary<Guid, DateTime>(); if (adapters.TryAdd(adapter, idList)) { adapter.AddOnMessageReceivedCallback(OnPrivateMessageReceivedCallback); adapter.RemoteClientUpdated += OnAdapterRemoteClientUpdated; adapter.RemoteClientRemoved += OnAdapterRemoteClientRemoved; foreach (var remoteClientId in adapter.GetAllRemoteClients()) { adapter.TryGetVirtualHosts(remoteClientId, out var settings); AddAdapterToAdapterOfClients(remoteClientId, adapter, settings); idList[remoteClientId] = DateTime.Now; } } else { return; } if (ConnectionErrorOccurredInternal != null) { adapter.ConnectionErrorOccurred += OnAdapterConnectionErrorOccurred; } if (AdapterStartedInternal != null) { adapter.AdapterStarted += OnAdapterStarted; } if (AdapterStoppedInternal != null) { adapter.AdapterStopped += OnAdapterStopped; } //get clients id KeyValuePair<Guid, IRemoteHubAdapter<byte[]>>[] allClients; lock (adapterOfClients) { allClients = adapterOfClients.Where(i => i.Value != adapter).ToArray(); } foreach (var client in allClients) { if (client.Value.TryGetVirtualHosts(client.Key, out var settings)) { adapter.ApplyVirtualHosts(client.Key, settings); //will add client if not existed. } } adapter.Start(); AdapterAdded?.Invoke(this, new AdapterEventArgs(adapter)); }
/// <summary> /// Gets all remote clients registered with the adapter and being used, not replaced by other adapters, in this RemoteHub Switch instance. /// </summary> /// <param name="adapter">The adapter for being querying.</param> /// <returns>Ids of the remote clients registered with the adapter specified and being used, not replaced by other adapters, in this RemoteHub Switch instance. <see langword="null"/> will be returned if the adapter specified is not registered with this RemoteHub Switch instance.</returns> public IEnumerable<Guid> GetActiveRemoteClientsOfAdapter(IRemoteHubAdapter<byte[]> adapter) { if (adapters.TryGetValue(adapter, out var set)) { lock (set) { return set.Keys.ToArray(); } } else { return null; } }
/// <summary> /// Removes an adapter from this switch. /// </summary> /// <param name="adapter">Adapter to be removed.</param> /// <param name="stopAdapter">Whether the adapter should be stopped after removal. Default value is <see langword="false"/>.</param> public void RemoveAdapter(IRemoteHubAdapter<byte[]> adapter, bool stopAdapter = false) { adapter.RemoteClientUpdated -= OnAdapterRemoteClientUpdated; adapter.RemoteClientRemoved -= OnAdapterRemoteClientRemoved; adapter.RemoveOnMessageReceivedCallback(OnPrivateMessageReceivedCallback); if (adapters.TryGetValue(adapter, out var idList)) { if (adapters.TryRemove(adapter, out _)) { foreach (var remoteClientId in idList.Keys) { RemoveAdapterFromAdapterOfClients(remoteClientId, adapter); } } else { return; } } else { return; } if (stopAdapter) { adapter.Stop(); //don't need to remove clients due to stopping applied. } else { //remove clients from the adapter being removed. Guid[] allClientId; lock (adapterOfClients) { allClientId = adapterOfClients.Where(i => i.Value != adapter).Select(i => i.Key).ToArray(); } adapter.RemoveClient(allClientId); } adapter.ConnectionErrorOccurred -= OnAdapterConnectionErrorOccurred; adapter.AdapterStarted -= OnAdapterStarted; adapter.AdapterStopped -= OnAdapterStopped; AdapterRemoved?.Invoke(this, new AdapterEventArgs(adapter)); }
void RemoveAdapterFromAdapterOfClients(Guid remoteClientId, IRemoteHubAdapter<byte[]> adapter) { lock (adapterOfClients) //lock while changing { if (adapterOfClients.TryGetValue(remoteClientId, out var old) && old == adapter) { adapterOfClients.TryRemove(remoteClientId, out _); RemoteClientRemoved?.Invoke(this, new RemoteClientChangedEventArgs(remoteClientId, adapter)); } else { return; } } //broadcast var allAdapters = adapters.Keys.ToArray(); foreach (var target in allAdapters) { if (target != adapter) target.RemoveClient(remoteClientId); } }
void AddAdapterToAdapterOfClients(Guid remoteClientId, IRemoteHubAdapter<byte[]> adapter, KeyValuePair<Guid, VirtualHostSetting>[] virtuaHostSetting) { lock (adapterOfClients) //lock while changing { if (adapterOfClients.TryGetValue(remoteClientId, out var old)) { if (old != adapter) { adapterOfClients[remoteClientId] = adapter; if (adapters.TryGetValue(old, out var idList)) { idList.TryRemove(remoteClientId, out _); } RemoteClientChanged?.Invoke(this, new RemoteClientChangedEventArgs(remoteClientId, adapter)); } } else { adapterOfClients[remoteClientId] = adapter; RemoteClientAdded?.Invoke(this, new RemoteClientChangedEventArgs(remoteClientId, adapter)); } } //broadcast var allAdapters = adapters.Keys.ToArray(); foreach (var target in allAdapters) { if (target != adapter) { //target.AddClient(remoteClientId); target.ApplyVirtualHosts(remoteClientId, virtuaHostSetting); //will add client if not exists. } } }
/// <summary> /// Initializes an instance of AdapterEventArgs. /// </summary> /// <param name="remoteHubAdapter">Related RemoteHub Adapter instance.</param> public AdapterEventArgs(IRemoteHubAdapter <byte[]> remoteHubAdapter) { Adapter = remoteHubAdapter; }
internal MessageRoutedEventArgs(Guid clientId, IRemoteHubAdapter <byte[]> adapter, byte[] message) : base(clientId) { Adapter = adapter; Message = message; }
internal RemoteClientChangedEventArgs(Guid clientId, IRemoteHubAdapter <byte[]> adapter) : base(clientId) { Adapter = adapter; }
/// <summary> /// Initializes an instance of ConnectionExceptionWithAdapterEventArgs. /// </summary> /// <param name="e">The argument passed by <see cref="IRemoteHubAdapter.ConnectionErrorOccurred"/>.</param> /// <param name="remoteHubAdapter">RemoteHub Adapter instance which throw the exception.</param> public ConnectionExceptionWithAdapterEventArgs(ConnectionExceptionEventArgs e, IRemoteHubAdapter <byte[]> remoteHubAdapter) : base(e.Exception, e.IsFatal, e.IsRetried) { Adapter = remoteHubAdapter; }