예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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.");
            }
        }