public void DefaultKeepAliveThrowsWhenNegative() { // Arrange var config = new DefaultConfigurationManager(); // Assert Assert.Throws(typeof(ArgumentOutOfRangeException), () => config.KeepAlive = -1); }
public void KeepAliveThrowsWhenZero() { // Arrange var config = new DefaultConfigurationManager(); // Assert Assert.Throws(typeof(ArgumentOutOfRangeException), () => config.KeepAlive = TimeSpan.FromSeconds(0)); }
public void DefaultValues() { // Arrange var config = new DefaultConfigurationManager(); // Assert Assert.Equal(config.ConnectionTimeout.TotalSeconds, 110); Assert.Equal(config.DisconnectTimeout.TotalSeconds, 40); Assert.Equal(config.HeartbeatInterval.TotalSeconds, 10); Assert.Equal(config.KeepAlive, 2); }
public void DefaultValues() { // Arrange var config = new DefaultConfigurationManager(); // Assert Assert.Equal(110, config.ConnectionTimeout.TotalSeconds); Assert.Equal(30, config.DisconnectTimeout.TotalSeconds); Assert.Equal(10, config.KeepAlive.Value.TotalSeconds); Assert.Equal(20, config.KeepAliveTimeout().Value.TotalSeconds); Assert.Equal(5, config.HeartbeatInterval().TotalSeconds); Assert.Equal(100, config.TopicTtl().TotalSeconds); }
public void TwoSecondsAndNullOnlyValidKeepAliveValuesWhenDisconnectTimeoutIsSixSeconds() { // Arrange var config = new DefaultConfigurationManager(); config.DisconnectTimeout = TimeSpan.FromSeconds(6); // Assert Assert.Throws(typeof(ArgumentOutOfRangeException), () => config.KeepAlive = TimeSpan.FromSeconds(1.99)); Assert.Throws(typeof(ArgumentOutOfRangeException), () => config.KeepAlive = TimeSpan.FromSeconds(2.01)); // Assert doesn't throw config.KeepAlive = TimeSpan.FromSeconds(2); config.KeepAlive = null; }
public async Task FarmDisconnectRaisesUncleanDisconnects() { // Each node shares the same bus but are independent servers const int nodeCount = 3; var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); configurationManager.DisconnectTimeout = TimeSpan.FromSeconds(6); using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var loadBalancer = new LoadBalancer(nodeCount)) { var broadcasters = new List<IConnection>(); var disconnectCounter = new DisconnectCounter(); loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); resolver.Register(typeof(IConfigurationManager), () => configurationManager); resolver.Register(typeof(FarmConnection), () => new FarmConnection(disconnectCounter)); var connectionManager = resolver.Resolve<IConnectionManager>(); broadcasters.Add(connectionManager.GetConnectionContext<FarmConnection>().Connection); app.MapSignalR<FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); }); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); await connection.Start(transport); for (int i = 0; i < nodeCount; i++) { broadcasters[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)).Wait(); await Task.Delay(TimeSpan.FromSeconds(1)); } ((Client.IConnection)connection).Disconnect(); await Task.Delay(TimeSpan.FromTicks(TimeSpan.FromSeconds(5).Ticks * nodeCount)); Assert.Equal(0, disconnectCounter.CleanDisconnectCount); Assert.Equal(3, disconnectCounter.UncleanDisconnectCount); } }
public void KeepAliveThrowsWhenGreaterThanAThirdOfTheDisconnectTimeout() { // Arrange var config = new DefaultConfigurationManager(); // Assert Assert.Throws(typeof(ArgumentOutOfRangeException), () => config.KeepAlive = TimeSpan.FromSeconds(10.01)); config.KeepAlive = TimeSpan.FromSeconds(10); // Arrange config = new DefaultConfigurationManager(); config.DisconnectTimeout = TimeSpan.FromSeconds(15); // Assert Assert.Throws(typeof(ArgumentOutOfRangeException), () => config.KeepAlive = TimeSpan.FromSeconds(5.01)); config.KeepAlive = TimeSpan.FromSeconds(5); }
public void TopicTopicTimeToLiveIsDoubleTheDisconnectTimeoutWhenKeepAliveIsNull() { var config = new DefaultConfigurationManager(); var random = new Random(); config.DisconnectTimeout = TimeSpan.FromSeconds(random.Next(6, 31536000)); // 12 seconds to a year config.KeepAlive = null; // Assert Assert.Equal(TimeSpan.FromTicks(config.DisconnectTimeout.Ticks * 2), config.TopicTtl()); }
public void HeartbeatIntervalIsHalfTheKeepAlive() { // Arrange var config = new DefaultConfigurationManager(); var random = new Random(); config.KeepAlive = TimeSpan.FromSeconds(random.NextDouble() * 8 + 2); // 2 to 10 seconds // Assert Assert.Equal(TimeSpan.FromTicks(config.KeepAlive.Value.Ticks / 2), config.HeartbeatInterval()); }
public void KeepAliveTimeoutIsTwiceTheKeepAlive() { // Arrange var config = new DefaultConfigurationManager(); var random = new Random(); config.KeepAlive = TimeSpan.FromSeconds(random.NextDouble() * 8 + 2); // 2 to 10 seconds // Assert Assert.Equal(TimeSpan.FromTicks(config.KeepAlive.Value.Ticks * 2), config.KeepAliveTimeout()); // Arrange config.KeepAlive = null; // Assert Assert.Equal(null, config.KeepAliveTimeout()); }
public void KeepAliveCannotBeConfiguredBeforeDisconnectTimeout() { // Arrange var config = new DefaultConfigurationManager(); config.KeepAlive = TimeSpan.FromSeconds(5); // Assert Assert.Throws(typeof(InvalidOperationException), () => config.DisconnectTimeout = TimeSpan.FromSeconds(40)); // Arrange config = new DefaultConfigurationManager(); config.KeepAlive = null; // Assert Assert.Throws(typeof(InvalidOperationException), () => config.DisconnectTimeout = TimeSpan.FromSeconds(40)); }
public void SettingDisconnectTimeoutSetKeepAliveToAThirdOfItself() { // Arrange var config = new DefaultConfigurationManager(); var random = new Random(); config.DisconnectTimeout = TimeSpan.FromSeconds(random.Next(6, 31536000)); // 6 seconds to a year // Assert Assert.Equal(TimeSpan.FromTicks(config.DisconnectTimeout.Ticks / 3), config.KeepAlive); }
public void DisconnectTimeoutThrowsWhenLessThanSixSeconds() { // Arrange var config = new DefaultConfigurationManager(); // Assert Assert.Throws(typeof(ArgumentOutOfRangeException), () => config.DisconnectTimeout = TimeSpan.FromSeconds(5.99)); config.DisconnectTimeout = TimeSpan.FromSeconds(6); }
public async Task FarmDisconnectOnlyRaisesUncleanDisconnects() { EnableTracing(); // Each node shares the same bus but are indepenent servers var counters = new SignalR.Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); var protectedData = new DefaultProtectedData(); using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) { var nodeCount = 3; var nodes = new List<ServerNode>(); for (int i = 0; i < nodeCount; i++) { nodes.Add(new ServerNode(bus)); } var timeout = TimeSpan.FromSeconds(5); foreach (var node in nodes) { var config = node.Resolver.Resolve<IConfigurationManager>(); config.DisconnectTimeout = TimeSpan.FromSeconds(6); IDependencyResolver resolver = node.Resolver; node.Server.Configure(app => { app.MapSignalR<FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); resolver.Register(typeof(IProtectedData), () => protectedData); }); } var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray()); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); await connection.Start(transport); for (int i = 0; i < nodes.Count; i++) { nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)); await Task.Delay(TimeSpan.FromSeconds(1)); } ((Client.IConnection)connection).Disconnect(); await Task.Delay(TimeSpan.FromTicks(timeout.Ticks * nodes.Count)); Assert.Equal(0, FarmConnection.OldOnDisconnectedCalls); Assert.Equal(0, FarmConnection.CleanDisconnectCount); Assert.Equal(3, FarmConnection.UncleanDisconnectCount); } }
public void FarmDisconnectOnlyRaisesEventOnce() { // Each node shares the same bus but are indepenent servers var counters = new SignalR.Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) { var nodeCount = 3; var nodes = new List<ServerNode>(); for (int i = 0; i < nodeCount; i++) { nodes.Add(new ServerNode(bus)); } var timeout = TimeSpan.FromSeconds(5); foreach (var node in nodes) { var config = node.Resolver.Resolve<IConfigurationManager>(); config.DisconnectTimeout = TimeSpan.FromSeconds(6); IDependencyResolver resolver = node.Resolver; node.Server.Configure(app => { app.MapConnection<FarmConnection>("/echo", new ConnectionConfiguration { Resolver = resolver }); }); } var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray()); var transport = new Client.Transports.LongPollingTransport(loadBalancer); var connection = new Client.Connection("http://goo/echo"); connection.Start(transport).Wait(); for (int i = 0; i < nodes.Count; i++) { nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1)); Thread.Sleep(TimeSpan.FromSeconds(1)); } connection.Disconnect(); Thread.Sleep(TimeSpan.FromTicks(timeout.Ticks * nodes.Count)); Assert.Equal(1, nodes.Sum(n => n.Connection.DisconnectCount)); } }
public void DisconnectTimeoutThrowsWhenNegative() { // Arrange var config = new DefaultConfigurationManager(); // Assert Assert.Throws(typeof(ArgumentOutOfRangeException), () => config.KeepAlive = TimeSpan.FromSeconds(-1)); }
public async Task ContextGroupAddCompletesSuccessfully() { // https://github.com/SignalR/SignalR/issues/3337 // Each node shares the same bus but are independent servers var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var memoryHost = new MemoryHost()) { memoryHost.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); app.MapSignalR(new HubConfiguration { Resolver = resolver }); }); using (var connection = new HubConnection("http://goo/")) { var proxy = connection.CreateHubProxy("FarmGroupHub"); const string group = "group"; const string message = "message"; var mre = new AsyncManualResetEvent(); proxy.On<string>("message", m => { if (m == message) { mre.Set(); } }); await connection.Start(memoryHost); // Add the connection to a group via an IHubContext on a "second" server. var secondResolver = new DefaultDependencyResolver(); secondResolver.Register(typeof(IMessageBus), () => bus); var secondConnectionManager = secondResolver.Resolve<IConnectionManager>(); var secondHubContext = secondConnectionManager.GetHubContext<FarmGroupHub>(); await secondHubContext.Groups.Add(connection.ConnectionId, group); await proxy.Invoke("SendToGroup", group, message); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public void HeartbeatIntervalIsASixthOfTheDisconnectTimeoutIfTheKeepAliveIsNull() { // Arrange var config = new DefaultConfigurationManager(); var random = new Random(); config.DisconnectTimeout = TimeSpan.FromSeconds(random.Next(6, 31536000)); // 6 seconds to a year config.KeepAlive = null; // Assert Assert.Equal(TimeSpan.FromTicks(config.DisconnectTimeout.Ticks / 6), config.HeartbeatInterval()); }
public async Task FarmGroupAddCompletesSuccessfully(TransportType transportType) { // https://github.com/SignalR/SignalR/issues/3337 // Each node shares the same bus but are independent servers const int nodeCount = 2; var counters = new Infrastructure.PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); // Ensure /send and /connect requests get handled by different servers Func<string, int> scheduler = url => url.Contains("/send") ? 0 : 1; using (EnableDisposableTracing()) using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000)) using (var loadBalancer = new LoadBalancer(nodeCount, scheduler)) { loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); app.MapSignalR(new HubConfiguration { Resolver = resolver }); }); using (var connection = new HubConnection("http://goo/")) { var proxy = connection.CreateHubProxy("FarmGroupHub"); const string group = "group"; const string message = "message"; var mre = new AsyncManualResetEvent(); proxy.On<string>("message", m => { if (m == message) { mre.Set(); } }); Client.Transports.IClientTransport transport; switch (transportType) { case TransportType.LongPolling: transport = new Client.Transports.LongPollingTransport(loadBalancer); break; case TransportType.ServerSentEvents: transport = new Client.Transports.ServerSentEventsTransport(loadBalancer); break; default: throw new ArgumentException("transportType"); } await connection.Start(transport); await proxy.Invoke("JoinGroup", group); await proxy.Invoke("SendToGroup", group, message); Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5))); } } }
public void TopicTimeToLiveIsDoubleTheDisconnectAndKeepAliveTimeouts() { var config = new DefaultConfigurationManager(); var random = new Random(); config.DisconnectTimeout = TimeSpan.FromSeconds(random.Next(12, 31536000)); // 12 seconds to a year config.KeepAlive = TimeSpan.FromTicks(config.DisconnectTimeout.Ticks / 6); // Set custom keep-alive to half the default // Assert Assert.Equal(TimeSpan.FromTicks(config.DisconnectTimeout.Ticks * 2 + config.KeepAliveTimeout().Value.Ticks * 2), config.TopicTtl()); }