/// <summary> /// The middleware used for forwarding incoming hub messages to other servers. /// </summary> /// <param name="config">DotNetify configuration.</param> /// <param name="serverUrls">Array of URLs of the servers to forward messages to.</param> /// <param name="haltPipeline">Whether to prevent further processing in this server after forwarding messages.</param> public static IDotNetifyConfiguration UseForwarding(this IDotNetifyConfiguration config, string[] serverUrls, Action <ForwardingOptions> optionsAccessor = null) { for (int i = 0; i < serverUrls.Length; i++) { var forwardingOptions = new ForwardingOptions(); optionsAccessor?.Invoke(forwardingOptions); if (i < serverUrls.Length - 1) { forwardingOptions.HaltPipeline = false; } config.UseMiddleware <ForwardingMiddleware>(serverUrls[i], forwardingOptions); } return(config); }
private DotNetifyHubForwarder CreateInstance(string serverUrl, ForwardingOptions config) { var hubProxy = _hubProxyFactory.GetInstance(); if (config.UseMessagePack) { (hubProxy as DotNetifyHubProxy).ConnectionBuilder = builder => builder.AddMessagePackProtocol(); } else { (hubProxy as DotNetifyHubProxy).ConnectionBuilder = builder => builder.AddJsonProtocol(); } hubProxy.Init(null, serverUrl); return(new DotNetifyHubForwarder(hubProxy, new DotNetifyHubResponse(_globalHubContext))); }
public async Task InvokeInstanceAsync(string serverUrl, ForwardingOptions config, Func <DotNetifyHubForwarder, Task> invoke) { var pool = GetConnectionPool(serverUrl, config); var hubForwarder = await pool.TakeAsync(); var semaphore = _semaphores.GetOrAdd(hubForwarder, _ => new SemaphoreSlim(1)); await semaphore.WaitAsync(); await hubForwarder.StartAsync(); try { await invoke(hubForwarder); } catch (Exception ex) { throw new ForwardingException(ex.Message, ex); } finally { semaphore.Release(); _ = pool.AddAsync(hubForwarder); } }
/// <summary> /// Class constructor. /// </summary> /// <param name="hubForwarderFactory">Factory of hub message forwarder objects.</param> /// <param name="serverUrl">URL of the server to forward messages to.</param> /// <param name="config">Forwarding configuration.</param> public ForwardingMiddleware(IDotNetifyHubForwarderFactory hubForwarderFactory, string serverUrl, ForwardingOptions config) { _hubForwarderFactory = hubForwarderFactory; _serverUrl = serverUrl; _config = config; }
private AsyncCollection <DotNetifyHubForwarder> GetConnectionPool(string serverUrl, ForwardingOptions config) { return(_hubForwarders.GetOrAdd(serverUrl, url => { var newForwarders = Enumerable.Range(1, config.ConnectionPoolSize).Select(x => CreateInstance(serverUrl, config)); return new AsyncCollection <DotNetifyHubForwarder>(new ConcurrentQueue <DotNetifyHubForwarder>(newForwarders)); })); }