public void TestWeakConnectionStatus() { using (StartVerifiableLog(out var loggerFactory, LogLevel.Warning, expectedErrors: e => true, logChecker: s => { Assert.Single(s); Assert.Equal("EndpointOffline", s[0].Write.EventId.Name); return(true); })) { var endpoint1 = new HubServiceEndpoint(); var conn1 = new TestServiceConnection(); var scf = new TestServiceConnectionFactory(endpoint1 => conn1); var container = new WeakServiceConnectionContainer(scf, 5, endpoint1, loggerFactory.CreateLogger(nameof(TestWeakConnectionStatus))); // When init, consider the endpoint as online // TODO: improve the logic Assert.True(endpoint1.Online); conn1.SetStatus(ServiceConnectionStatus.Connecting); Assert.True(endpoint1.Online); conn1.SetStatus(ServiceConnectionStatus.Connected); Assert.True(endpoint1.Online); conn1.SetStatus(ServiceConnectionStatus.Disconnected); Assert.False(endpoint1.Online); conn1.SetStatus(ServiceConnectionStatus.Connecting); Assert.False(endpoint1.Online); conn1.SetStatus(ServiceConnectionStatus.Connected); Assert.True(endpoint1.Online); } }
public void TestGetServiceStatus(bool[] pingStatus, int checkWindow, int checkMilli, bool expectedStatus) { var endpoint = new TestHubServiceEndpoint(); var container = new WeakServiceConnectionContainer(null, 0, endpoint, NullLogger.Instance); var checkTimeSpan = TimeSpan.FromMilliseconds(checkMilli); bool status = true; foreach (var ping in pingStatus) { status = container.GetServiceStatus(ping, checkWindow, checkTimeSpan); } Assert.Equal(expectedStatus, status); }
public async Task<IServiceHubContext> CreateHubContextAsync(string hubName, ILoggerFactory loggerFactory = null, CancellationToken cancellationToken = default) { loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; switch (_serviceManagerOptions.ServiceTransportType) { case ServiceTransportType.Persistent: { var connectionFactory = new ManagementConnectionFactory(_productInfo, new ConnectionFactory(_serverNameProvider, loggerFactory)); var serviceProtocol = new ServiceProtocol(); var clientConnectionManager = new ClientConnectionManager(); var clientConnectionFactory = new ClientConnectionFactory(); ConnectionDelegate connectionDelegate = connectionContext => Task.CompletedTask; var serviceConnectionFactory = new ServiceConnectionFactory(serviceProtocol, clientConnectionManager, connectionFactory, loggerFactory, connectionDelegate, clientConnectionFactory); var weakConnectionContainer = new WeakServiceConnectionContainer( serviceConnectionFactory, _serviceManagerOptions.ConnectionCount, new HubServiceEndpoint(hubName, _endpointProvider, _endpoint), loggerFactory?.CreateLogger(nameof(WeakServiceConnectionContainer)) ?? NullLogger.Instance); var serviceCollection = new ServiceCollection(); serviceCollection.AddSignalRCore(); serviceCollection.AddSingleton<IConfigureOptions<HubOptions>, ManagementHubOptionsSetup>(); if (loggerFactory != null) { serviceCollection.AddSingleton(typeof(ILoggerFactory), loggerFactory); } serviceCollection .AddLogging() .AddSingleton(typeof(IConnectionFactory), sp => connectionFactory) .AddSingleton(typeof(HubLifetimeManager<>), typeof(WebSocketsHubLifetimeManager<>)) .AddSingleton(typeof(IServiceConnectionManager<>), typeof(ServiceConnectionManager<>)) .AddSingleton(typeof(IServiceConnectionContainer), sp => weakConnectionContainer); var success = false; ServiceProvider serviceProvider = null; try { serviceProvider = serviceCollection.BuildServiceProvider(); var serviceConnectionManager = serviceProvider.GetRequiredService<IServiceConnectionManager<Hub>>(); serviceConnectionManager.SetServiceConnection(weakConnectionContainer); _ = serviceConnectionManager.StartAsync(); // wait until service connection established await weakConnectionContainer.ConnectionInitializedTask.OrTimeout(cancellationToken); var webSocketsHubLifetimeManager = (WebSocketsHubLifetimeManager<Hub>)serviceProvider.GetRequiredService<HubLifetimeManager<Hub>>(); var hubContext = serviceProvider.GetRequiredService<IHubContext<Hub>>(); var serviceHubContext = new ServiceHubContext(hubContext, webSocketsHubLifetimeManager, serviceProvider); success = true; return serviceHubContext; } finally { if (!success) { serviceProvider?.Dispose(); } } } case ServiceTransportType.Transient: { var serviceCollection = new ServiceCollection(); serviceCollection.AddSignalRCore(); // remove default hub lifetime manager var serviceDescriptor = serviceCollection.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(HubLifetimeManager<>)); serviceCollection.Remove(serviceDescriptor); // add rest hub lifetime manager var restHubLifetimeManager = new RestHubLifetimeManager(_serviceManagerOptions, hubName, _productInfo); serviceCollection.AddSingleton(typeof(HubLifetimeManager<Hub>), sp => restHubLifetimeManager); var serviceProvider = serviceCollection.BuildServiceProvider(); var hubContext = serviceProvider.GetRequiredService<IHubContext<Hub>>(); return new ServiceHubContext(hubContext, restHubLifetimeManager, serviceProvider); } default: throw new ArgumentException("Not supported service transport type."); } }