public void CanRegisterAndResolveTypes() { var resolver = new DefaultDependencyResolver(); resolver.Register <IServiceA, ServiceA>(); var s1 = resolver.Resolve <IServiceA>(); var s2 = resolver.Resolve <IServiceA>(); Assert.Equal(s1, s2); }
public void CanInjectConstructors() { var resolver = new DefaultDependencyResolver(); resolver.Register <IServiceA, ServiceA>(); resolver.Register <IServiceB, ServiceB>(); var a = resolver.Resolve <IServiceA>(); var b = resolver.Resolve <IServiceB>(); Assert.Equal(a, b.ServiceA); Assert.NotNull(b.ServiceC); }
public void GetTopicDoesNotChangeStateWhenNotDying() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { bus.Subscribe(new TestSubscriber(new[] { "key" }), null, (result, state) => TaskAsyncHelper.True, 10, null); Topic topic; Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); topic = bus.GetTopic("key"); Assert.Equal(TopicState.HasSubscriptions, topic.State); topic.RemoveSubscription(topic.Subscriptions.First()); Assert.Equal(TopicState.NoSubscriptions, topic.State); topic = bus.GetTopic("key"); Assert.Equal(TopicState.NoSubscriptions, topic.State); topic.State = TopicState.Dying; topic = bus.GetTopic("key"); Assert.Equal(TopicState.NoSubscriptions, topic.State); } }
public async Task DisconnectFiresForPersistentConnectionWhenClientDisconnects() { using (var host = new MemoryHost()) { var connectWh = new AsyncManualResetEvent(); var disconnectWh = new AsyncManualResetEvent(); var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = dr }; app.MapSignalR <MyConnection>("/echo", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyConnection), () => new MyConnection(connectWh, disconnectWh)); }); var connection = new Client.Connection("http://foo/echo"); await connection.Start(host); Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired"); ((Client.IConnection)connection).Disconnect(); Assert.True(await disconnectWh.WaitAsync(TimeSpan.FromSeconds(20)), "Disconnect never fired"); } }
public async Task DisconnectFiresForHubsWhenClientDisconnects() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); var connectWh = new TaskCompletionSource <object>(); var disconnectWh = new TaskCompletionSource <object>(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapSignalR("/signalr", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); await connection.Start(host); await connectWh.Task.OrTimeout(TimeSpan.FromSeconds(10)); ((Client.IConnection)connection).Disconnect(); await disconnectWh.Task.OrTimeout(TimeSpan.FromSeconds(20)); } }
public ChatHub(string username, string password) { var identity = new GenericIdentity("*****@*****.**"); identity.AddClaim(new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.NameIdentifier, "2", System.Security.Claims.ClaimValueTypes.Integer)); identity.AddClaim(new System.Security.Claims.Claim("NickName", "ibrahim", System.Security.Claims.ClaimValueTypes.Integer)); //Thread.CurrentPrincipal = new GenericPrincipal(identity, null); //ApplicationSignInManager c = new ApplicationSignInManager("sa", HttpContext.GetOwinContext().Authentication) //SignInManager.PasswordSignIn(username, password, true, true); const string connectionId = "1234"; const string hubName = "ChatHub"; var resolver = new DefaultDependencyResolver(); _config = resolver.Resolve <IConfigurationManager>(); var mockConnection = new Mock <IConnection>(); var mockUser = new Mock <IPrincipal>(); //var mockCookies = new Mock<IRequestCookieCollection>(); var mockHubPipelineInvoker = new Mock <IHubPipelineInvoker>(); //IHubPipelineInvoker _pipelineInvoker = resolver.Resolve<IHubPipelineInvoker>(); var mockRequest = new Mock <IRequest>(); mockRequest.Setup(r => r.User).Returns(new GenericPrincipal(identity, null)); //mockRequest.Setup(r => r.Cookies).Returns(mockCookies.Object); StateChangeTracker tracker = new StateChangeTracker(); //Clients = new HubConnectionContext(_pipelineInvoker, mockConnection.Object, hubName, connectionId, tracker); Clients = new HubConnectionContext(mockHubPipelineInvoker.Object, mockConnection.Object, hubName, connectionId, tracker); Context = new HubCallerContext(mockRequest.Object, connectionId); var x = Clients.Caller; }
public void GarbageCollectingTopicsAfterGettingTopicsNoops() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; bus.AfterTopicMarkedSuccessfully = (key, topic) => { bus.GarbageCollectTopics(); }; try { subscription = bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null); Assert.Equal(1, bus.Topics.Count); Topic topic; Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } finally { if (subscription != null) { subscription.Dispose(); } } } }
private static void RunConnectionTest() { string payload = GetPayload(); var dr = new DefaultDependencyResolver(); MeasureStats((MessageBus)dr.Resolve <IMessageBus>()); var connectionManager = new ConnectionManager(dr); var context = connectionManager.GetConnectionContext <StressConnection>(); for (int i = 0; i < _clients; i++) { ThreadPool.QueueUserWorkItem(state => { Interlocked.Increment(ref _clientsRunning); var transportConnection = (ITransportConnection)context.Connection; transportConnection.Receive(null, r => { Interlocked.Add(ref _received, r.TotalCount); Interlocked.Add(ref _avgLastReceivedCount, r.TotalCount); return(TaskAsyncHelper.True); }, maxMessages: 10); }, i); } for (var i = 1; i <= _senders; i++) { ThreadPool.QueueUserWorkItem(_ => { StartSendLoop(i.ToString(), (source, key, value) => context.Connection.Broadcast(value), payload); }); } }
private static void RunConnectionReceiveLoopTest() { string payload = GetPayload(); var dr = new DefaultDependencyResolver(); MeasureStats((MessageBus)dr.Resolve <IMessageBus>()); var connectionManager = new ConnectionManager(dr); var context = connectionManager.GetConnectionContext <StressConnection>(); for (int i = 0; i < _clients; i++) { ThreadPool.QueueUserWorkItem(state => { Interlocked.Increment(ref _clientsRunning); var transportConnection = (ITransportConnection)context.Connection; ReceiveLoop(transportConnection, null); }, i); } for (var i = 1; i <= _senders; i++) { ThreadPool.QueueUserWorkItem(_ => { StartSendLoop(i.ToString(), (source, key, value) => context.Connection.Broadcast(value), payload); }); } }
public void CanResolveUnregisteredType() { var resolver = new DefaultDependencyResolver(); var s1 = resolver.Resolve <ServiceA>(); Assert.NotNull(s1); }
public void DisposablesAreTrackedAndDisposed() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(MyDisposable), () => new MyDisposable()); var disposable = resolver.Resolve<MyDisposable>(); resolver.Dispose(); Assert.True(disposable.Disposed); }
public void SubscriptionDoesNotGetNewMessagesWhenTopicStoreOverrunByOtherStream() { var dr = new DefaultDependencyResolver(); dr.Resolve <IConfigurationManager>().DefaultMessageBufferSize = 10; using (var bus = new TestScaleoutBus(dr, streams: 2)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; // The min fragment size is 8 and min fragments is 5 var expectedValues = Enumerable.Range(171, 8); var cd = new OrderedCountDownRange <int>(expectedValues); // This will overwrite the buffer ending up with (40 - 79) for stream 2 for (int i = 0; i < 80; i++) { bus.Publish(0, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } // This will overwrite the buffer with (140 - 179) for stream 1 for (int i = 100; i < 180; i++) { bus.Publish(1, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } try { subscription = bus.Subscribe(subscriber, "s-0,27|1,AA", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); cd.Expect(n); } return(TaskAsyncHelper.True); }, 100, null); Assert.True(cd.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionDoesNotGetNewMessagesWhenTopicStoreOverrunByOtherStream() { var dr = new DefaultDependencyResolver(); dr.Resolve<IConfigurationManager>().DefaultMessageBufferSize = 10; using (var bus = new TestScaleoutBus(dr, streams: 2)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; // The min fragment size is 8 and min fragments is 5 var expectedValues = Enumerable.Range(171, 8); var cd = new OrderedCountDownRange<int>(expectedValues); // This will overwrite the buffer ending up with (40 - 79) for stream 2 for (int i = 0; i < 80; i++) { bus.Publish(0, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } // This will overwrite the buffer with (140 - 179) for stream 1 for (int i = 100; i < 180; i++) { bus.Publish(1, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } try { subscription = bus.Subscribe(subscriber, "0,27|1,AA", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); cd.Expect(n); } return TaskAsyncHelper.True; }, 100, null); Assert.True(cd.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void DisposablesAreTrackedAndDisposed() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(MyDisposable), () => new MyDisposable()); var disposable = resolver.Resolve <MyDisposable>(); resolver.Dispose(); Assert.True(disposable.Disposed); }
public void Initialize(int keepAlive, int? connectionTimeout, int? disconnectTimeout, int? hearbeatInterval, bool enableAutoRejoiningGroups) { var dr = new DefaultDependencyResolver(); _host.Configure(app => { var configuration = dr.Resolve<IConfigurationManager>(); configuration.KeepAlive = keepAlive; if (connectionTimeout != null) { configuration.ConnectionTimeout = TimeSpan.FromSeconds(connectionTimeout.Value); } if (disconnectTimeout != null) { configuration.DisconnectTimeout = TimeSpan.FromSeconds(disconnectTimeout.Value); } if (hearbeatInterval != null) { configuration.HeartbeatInterval = TimeSpan.FromSeconds(hearbeatInterval.Value); } if (enableAutoRejoiningGroups) { dr.Resolve<IHubPipeline>().EnableAutoRejoiningGroups(); } app.MapHubs("/signalr", new HubConfiguration { Resolver = dr }); var config = new ConnectionConfiguration { Resolver = dr }; app.MapConnection<MyBadConnection>("/ErrorsAreFun", config); app.MapConnection<MyGroupEchoConnection>("/group-echo", config); app.MapConnection<MySendingConnection>("/multisend", config); app.MapConnection<MyReconnect>("/my-reconnect", config); app.MapConnection<MyGroupConnection>("/groups", config); app.MapConnection<MyRejoinGroupsConnection>("/rejoin-groups", config); app.MapConnection<FilteredConnection>("/filter", config); app.MapConnection<SyncErrorConnection>("/sync-error", config); app.MapConnection<FallbackToLongPollingConnection>("/fall-back", config); app.MapConnection<AddGroupOnConnectedConnection>("/add-group", config); }); }
public void CanHaveIsolatedContainers() { var resolver1 = new DefaultDependencyResolver(); var resolver2 = new DefaultDependencyResolver(); resolver1.Register <IServiceA, ServiceA>(); resolver2.Register <IServiceA, ServiceA>(); var s1 = resolver1.Resolve <IServiceA>(); var s2 = resolver2.Resolve <IServiceA>(); Assert.NotEqual(s1, s2); }
public void Initialize(int? keepAlive, int? connectionTimeout, int? disconnectTimeout, bool enableAutoRejoiningGroups) { var dr = new DefaultDependencyResolver(); _host.Configure(app => { var configuration = dr.Resolve<IConfigurationManager>(); if (connectionTimeout != null) { configuration.ConnectionTimeout = TimeSpan.FromSeconds(connectionTimeout.Value); } if (disconnectTimeout != null) { configuration.DisconnectTimeout = TimeSpan.FromSeconds(disconnectTimeout.Value); } if (!keepAlive.HasValue) { configuration.KeepAlive = null; } // Set only if the keep-alive was changed from the default value. else if (keepAlive.Value != -1) { configuration.KeepAlive = TimeSpan.FromSeconds(keepAlive.Value); } app.MapHubs("/signalr2/test", new HubConfiguration()); app.MapHubs("/signalr", new HubConfiguration { EnableDetailedErrors = true, Resolver = dr }); var config = new ConnectionConfiguration { Resolver = dr }; app.MapConnection<MyBadConnection>("/ErrorsAreFun", config); app.MapConnection<MyGroupEchoConnection>("/group-echo", config); app.MapConnection<MySendingConnection>("/multisend", config); app.MapConnection<MyReconnect>("/my-reconnect", config); app.MapConnection<MyGroupConnection>("/groups", config); app.MapConnection<MyRejoinGroupsConnection>("/rejoin-groups", config); app.MapConnection<FilteredConnection>("/filter", config); app.MapConnection<SyncErrorConnection>("/sync-error", config); app.MapConnection<FallbackToLongPollingConnection>("/fall-back", config); app.MapConnection<AddGroupOnConnectedConnection>("/add-group", config); app.MapConnection<UnusableProtectedConnection>("/protected", config); }); }
public void UntrackedDisposablesAreNotTracked() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(MyUntrackedDisposable), () => new MyUntrackedDisposable()); var untrackedDisposable = resolver.Resolve<MyUntrackedDisposable>(); var untrackedDisposableWeakRef = new WeakReference<MyUntrackedDisposable>(untrackedDisposable); untrackedDisposable = null; GC.Collect(); GC.WaitForPendingFinalizers(); Assert.False(untrackedDisposableWeakRef.TryGetTarget(out untrackedDisposable)); }
public void GetHubContextRejectsInvalidTypes() { var resolver = new DefaultDependencyResolver(); var manager = resolver.Resolve <IConnectionManager>(); Assert.Throws <InvalidOperationException>(() => manager.GetHubContext <DemoHub, IDontReturnVoidOrTask>()); Assert.Throws <InvalidOperationException>(() => manager.GetHubContext <DemoHub, IHaveOutParameter>()); Assert.Throws <InvalidOperationException>(() => manager.GetHubContext <DemoHub, IHaveRefParameter>()); Assert.Throws <InvalidOperationException>(() => manager.GetHubContext <DemoHub, IHaveProperties>()); Assert.Throws <InvalidOperationException>(() => manager.GetHubContext <DemoHub, IHaveIndexer>()); Assert.Throws <InvalidOperationException>(() => manager.GetHubContext <DemoHub, IHaveEvent>()); Assert.Throws <InvalidOperationException>(() => manager.GetHubContext <DemoHub, NotAnInterface>()); }
public async Task ContextGroupAddCompletesSuccessfully() { // https://github.com/SignalR/SignalR/issues/3337 // Each node shares the same bus but are independent servers var counters = new PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); using (EnableTracing()) 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 async Task FarmDisconnectRaisesUncleanDisconnects() { // Each node shares the same bus but are independent servers const int nodeCount = 3; var counters = new 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 FailedWriteCompletesRequestAfterDisconnectTimeout() { var request = new Mock <IRequest>(); var response = new Mock <IResponse>(); var qs = new NameValueCollection(); request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs)); var url = new Uri("http://test/echo/connect"); request.Setup(m => m.Url).Returns(url); request.Setup(m => m.LocalPath).Returns(url.LocalPath); var cts = new CancellationTokenSource(); response.Setup(m => m.CancellationToken).Returns(cts.Token); response.Setup(m => m.Flush()).Returns(TaskAsyncHelper.Empty); var resolver = new DefaultDependencyResolver(); var config = resolver.Resolve <IConfigurationManager>(); var hostContext = new HostContext(request.Object, response.Object); config.DisconnectTimeout = TimeSpan.FromSeconds(6); var transport = new Mock <ForeverTransport>(hostContext, resolver) { CallBase = true }; transport.Object.ConnectionId = "1"; transport.Setup(m => m.Send(It.IsAny <PersistentResponse>())) .Returns(() => { var task = TaskAsyncHelper.FromError(new Exception()); cts.Cancel(); return(task); }); var connectionManager = new ConnectionManager(resolver); var connection = connectionManager.GetConnectionCore("Foo"); var wh = new ManualResetEventSlim(); transport.Object.ProcessRequest(connection).ContinueWith(task => { wh.Set(); }); connection.Broadcast("Some message"); // 6 second disconnect timeout + 5 second disconnect threshold // + up to 1 second for the heartbeat to check + 3 second leeway Assert.True(wh.Wait(TimeSpan.FromSeconds(15))); }
public void UntrackedDisposablesAreNotTracked() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(MyUntrackedDisposable), () => new MyUntrackedDisposable()); var untrackedDisposable = resolver.Resolve <MyUntrackedDisposable>(); var untrackedDisposableWeakRef = new WeakReference <MyUntrackedDisposable>(untrackedDisposable); untrackedDisposable = null; GC.Collect(); GC.WaitForPendingFinalizers(); Assert.False(untrackedDisposableWeakRef.TryGetTarget(out untrackedDisposable)); }
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 HubReferencesAreNotRetained() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(DontLeakMeHub), () => new DontLeakMeHub()); var hub = resolver.Resolve<DontLeakMeHub>(); Assert.NotNull(hub); var hubWeakRef = new WeakReference<DontLeakMeHub>(hub); hub.Dispose(); hub = null; GC.Collect(); GC.WaitForPendingFinalizers(); Assert.False(hubWeakRef.TryGetTarget(out hub)); }
public void Configuration(IAppBuilder app) { app.UseFileServer(false); app.UseCors(CorsOptions.AllowAll); var projects = ConfigurationManager.AppSettings["sockets"]; foreach (var project in projects.Split(',')) { var resolver = new DefaultDependencyResolver(); /// Gets or sets the maximum size in bytes of messages sent from client to the server via WebSockets. /// Set to null to disable this limit. /// The default value is 65536 or 64 KB. /// 4MB == 4194304 resolver.Resolve <IConfigurationManager>().MaxIncomingWebSocketMessageSize = 4194304; resolver.Resolve <IConfigurationManager>().DisconnectTimeout = TimeSpan.FromSeconds(6); app.MapSignalR(@"/" + project.Trim(), new HubConfiguration { EnableJSONP = true, EnableDetailedErrors = true, Resolver = resolver }); } ; }
public void PublishingDoesNotCreateTopic() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { bus.Publish("test", "key", "1").Wait(); Assert.Equal(0, bus.Topics.Count); Assert.False(bus.Topics.ContainsKey("key")); } }
public void FailedWriteCompletesRequestAfterDisconnectTimeout() { var request = new Mock <IRequest>(); var response = new Mock <IResponse>(); var qs = new NameValueCollection(); qs["connectionId"] = "1"; request.Setup(m => m.QueryString).Returns(qs); request.Setup(m => m.Url).Returns(new Uri("http://test/echo/connect")); response.Setup(m => m.EndAsync()).Returns(TaskAsyncHelper.Empty); bool isConnected = true; response.Setup(m => m.IsClientConnected).Returns(() => isConnected); response.Setup(m => m.FlushAsync()).Returns(TaskAsyncHelper.Empty); var resolver = new DefaultDependencyResolver(); var config = resolver.Resolve <IConfigurationManager>(); var hostContext = new HostContext(request.Object, response.Object); config.DisconnectTimeout = TimeSpan.Zero; config.HeartbeatInterval = TimeSpan.FromSeconds(3); var transport = new Mock <ForeverTransport>(hostContext, resolver) { CallBase = true }; transport.Setup(m => m.Send(It.IsAny <PersistentResponse>())) .Returns(() => { var task = TaskAsyncHelper.FromError(new Exception()); isConnected = false; return(task); }); var connectionManager = new ConnectionManager(resolver); var connection = connectionManager.GetConnection("Foo"); var wh = new ManualResetEventSlim(); transport.Object.ProcessRequest(connection).ContinueWith(task => { wh.Set(); }); connection.Broadcast("Some message"); Assert.True(wh.Wait(TimeSpan.FromSeconds(10))); }
public void SubscriptionGetsNewMessagesWhenTopicStoreOverrun() { var dr = new DefaultDependencyResolver(); dr.Resolve <IConfigurationManager>().DefaultMessageBufferSize = 10; using (var bus = new TestScaleoutBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; // 16-49 is the valid range var cd = new OrderedCountDownRange <int>(Enumerable.Range(16, 33)); var results = new List <bool>(); for (int i = 0; i < 50; i++) { bus.Publish(0, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } try { subscription = bus.Subscribe(subscriber, "s-0,1", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); cd.Expect(n); } return(TaskAsyncHelper.True); }, 10, null); Assert.True(cd.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void FailedWriteCompletesRequestAfterDisconnectTimeout() { var request = new Mock<IRequest>(); var response = new Mock<IResponse>(); var qs = new NameValueCollection(); request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs)); var url = new Uri("http://test/echo/connect"); request.Setup(m => m.Url).Returns(url); request.Setup(m => m.LocalPath).Returns(url.LocalPath); var cts = new CancellationTokenSource(); response.Setup(m => m.CancellationToken).Returns(cts.Token); response.Setup(m => m.Flush()).Returns(TaskAsyncHelper.Empty); var resolver = new DefaultDependencyResolver(); var config = resolver.Resolve<IConfigurationManager>(); var hostContext = new HostContext(request.Object, response.Object); config.DisconnectTimeout = TimeSpan.FromSeconds(6); var transport = new Mock<ForeverTransport>(hostContext, resolver) { CallBase = true }; transport.Object.ConnectionId = "1"; transport.Setup(m => m.Send(It.IsAny<PersistentResponse>())) .Returns(() => { var task = TaskAsyncHelper.FromError(new Exception()); cts.Cancel(); return task; }); var connectionManager = new ConnectionManager(resolver); var connection = connectionManager.GetConnectionCore("Foo"); var wh = new ManualResetEventSlim(); transport.Object.ProcessRequest(connection).ContinueWith(task => { wh.Set(); }); connection.Broadcast("Some message"); // 6 second disconnect timeout + 5 second disconnect threshold // + up to 1 second for the heartbeat to check + 3 second leeway Assert.True(wh.Wait(TimeSpan.FromSeconds(15))); }
public void HubReferencesAreNotRetained() { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(DontLeakMeHub), () => new DontLeakMeHub()); var hub = resolver.Resolve <DontLeakMeHub>(); Assert.NotNull(hub); var hubWeakRef = new WeakReference <DontLeakMeHub>(hub); hub.Dispose(); hub = null; GC.Collect(); GC.WaitForPendingFinalizers(); Assert.False(hubWeakRef.TryGetTarget(out hub)); }
public void GarbageCollectingTopicsBeforeSubscribingTopicSetsStateToHasSubscription() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { bus.BeforeTopicMarked = (key, t) => { bus.GarbageCollectTopics(); }; Topic topic = bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } }
public void SubscribingTopicAfterNoSubscriptionsStateSetsStateToHasSubscription() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); Topic topic = bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } }
public void DisconnectFiresForHubsWhenConnectionGoesAway() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); var connectWh = new ManualResetEventSlim(); var disconnectWh = new ManualResetEventSlim(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapHubs("/signalr", config); configuration.DisconnectTimeout = TimeSpan.Zero; configuration.HeartbeatInterval = TimeSpan.FromSeconds(5); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new Client.Hubs.HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval.Ticks * 3); connection.Start(host).Wait(); Assert.True(connectWh.Wait(TimeSpan.FromSeconds(10)), "Connect never fired"); connection.Stop(); Assert.True(disconnectWh.Wait(disconnectWait), "Disconnect never fired"); } }
public async Task DisconnectFiresForHubsWhenClientCallsStop() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); var connectWh = new TaskCompletionSource <object>(); var disconnectWh = new TaskCompletionSource <object>(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapSignalR("/signalr", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval().Ticks * 3); await connection.Start(host); await connectWh.Task.OrTimeout(TimeSpan.FromSeconds(10)); connection.Stop(); await disconnectWh.Task.OrTimeout(disconnectWait); } }
public void DisconnectFiresForHubsWhenConnectionGoesAway() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); var connectWh = new ManualResetEventSlim(); var disconnectWh = new ManualResetEventSlim(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapSignalR("/signalr", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval().Ticks * 3); connection.Start(host).Wait(); Assert.True(connectWh.Wait(TimeSpan.FromSeconds(10)), "Connect never fired"); connection.Stop(); Assert.True(disconnectWh.Wait(disconnectWait), "Disconnect never fired"); } }
public async Task DisconnectFiresForPersistentConnectionWhenClientCallsStop() { using (var host = new MemoryHost()) { var connectWh = new AsyncManualResetEvent(); var disconnectWh = new AsyncManualResetEvent(); var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = dr }; app.MapSignalR <MyConnection>("/echo", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyConnection), () => new MyConnection(connectWh, disconnectWh)); }); var connection = new Client.Connection("http://foo/echo"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval().Ticks * 3); await connection.Start(host); Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired"); connection.Stop(); Assert.True(await disconnectWh.WaitAsync(disconnectWait), "Disconnect never fired"); } }
public async Task DisconnectFiresForPersistentConnectionWhenClientCallsStop() { using (var host = new MemoryHost()) { var connectWh = new AsyncManualResetEvent(); var disconnectWh = new AsyncManualResetEvent(); var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); host.Configure(app => { var config = new ConnectionConfiguration { Resolver = dr }; app.MapSignalR<MyConnection>("/echo", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyConnection), () => new MyConnection(connectWh, disconnectWh)); }); var connection = new Client.Connection("http://foo/echo"); // Maximum wait time for disconnect to fire (3 heart beat intervals) var disconnectWait = TimeSpan.FromTicks(configuration.HeartbeatInterval().Ticks * 3); await connection.Start(host); Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired"); connection.Stop(); Assert.True(await disconnectWh.WaitAsync(disconnectWait), "Disconnect never fired"); } }
public async Task FarmDisconnectRaisesUncleanDisconnects() { // Each node shares the same bus but are independent servers const int nodeCount = 3; var counters = new PerformanceCounterManager(); var configurationManager = new DefaultConfigurationManager(); configurationManager.DisconnectTimeout = TimeSpan.FromSeconds(6); using (EnableTracing()) 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 = Channel.CreateUnbounded <DisconnectData>(); loadBalancer.Configure(app => { var resolver = new DefaultDependencyResolver(); resolver.Register(typeof(IMessageBus), () => bus); resolver.Register(typeof(IConfigurationManager), () => configurationManager); resolver.Register(typeof(FarmConnection), () => new FarmConnection(disconnectCounter.Writer)); 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(); // Give up after 30 seconds var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(30)); // We can get duplicate OnDisconnected calls, and that's a known by-design issue. var instancesDisconnected = new HashSet <string>(); while (await disconnectCounter.Reader.WaitToReadAsync(cts.Token)) { while (!cts.IsCancellationRequested && disconnectCounter.Reader.TryRead(out var disconnect)) { Assert.False(disconnect.StopCalled, "Disconnect should not have been due to stop being called."); instancesDisconnected.Add(disconnect.InstanceName); if (instancesDisconnected.Count == 3) { // We're done, all three instances disconneted return; } } } // If we get here it means the cts was cancelled which means we timed out cts.Token.ThrowIfCancellationRequested(); } }
public void Initialize(int?keepAlive, int?connectionTimeout, int?disconnectTimeout, bool enableAutoRejoiningGroups) { var dr = new DefaultDependencyResolver(); _traceManager = dr.Resolve <ITraceManager>(); _traceManager.Switch.Level = SourceLevels.Verbose; foreach (var sourceName in _traceSources) { TraceSource source = _traceManager[sourceName]; source.Listeners.Add(_listener); } _host.Configure(app => { var configuration = dr.Resolve <IConfigurationManager>(); if (connectionTimeout != null) { configuration.ConnectionTimeout = TimeSpan.FromSeconds(connectionTimeout.Value); } if (disconnectTimeout != null) { configuration.DisconnectTimeout = TimeSpan.FromSeconds(disconnectTimeout.Value); } if (!keepAlive.HasValue) { configuration.KeepAlive = null; } // Set only if the keep-alive was changed from the default value. else if (keepAlive.Value != -1) { configuration.KeepAlive = TimeSpan.FromSeconds(keepAlive.Value); } app.MapHubs("/signalr2/test", new HubConfiguration()); app.MapHubs("/signalr", new HubConfiguration { EnableDetailedErrors = true, Resolver = dr }); var config = new ConnectionConfiguration { Resolver = dr }; app.MapConnection <MyBadConnection>("/ErrorsAreFun", config); app.MapConnection <MyGroupEchoConnection>("/group-echo", config); app.MapConnection <MySendingConnection>("/multisend", config); app.MapConnection <MyReconnect>("/my-reconnect", config); app.MapConnection <MyGroupConnection>("/groups", config); app.MapConnection <MyRejoinGroupsConnection>("/rejoin-groups", config); app.MapConnection <FilteredConnection>("/filter", config); app.MapConnection <SyncErrorConnection>("/sync-error", config); app.MapConnection <AddGroupOnConnectedConnection>("/add-group", config); app.MapConnection <UnusableProtectedConnection>("/protected", config); }); }
public async Task DisconnectFiresForHubsWhenClientDisconnects() { using (var host = new MemoryHost()) { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); var connectWh = new AsyncManualResetEvent(); var disconnectWh = new AsyncManualResetEvent(); host.Configure(app => { var config = new HubConfiguration { Resolver = dr }; app.MapSignalR("/signalr", config); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); dr.Register(typeof(MyHub), () => new MyHub(connectWh, disconnectWh)); }); var connection = new HubConnection("http://foo/"); connection.CreateHubProxy("MyHub"); await connection.Start(host); Assert.True(await connectWh.WaitAsync(TimeSpan.FromSeconds(10)), "Connect never fired"); ((Client.IConnection)connection).Disconnect(); Assert.True(await disconnectWh.WaitAsync(TimeSpan.FromSeconds(20)), "Disconnect never fired"); } }
public void FailedWriteCompletesRequestAfterDisconnectTimeout() { var request = new Mock<IRequest>(); var response = new Mock<IResponse>(); var qs = new NameValueCollection(); qs["connectionId"] = "1"; request.Setup(m => m.QueryString).Returns(qs); request.Setup(m => m.Url).Returns(new Uri("http://test/echo/connect")); response.Setup(m => m.End()).Returns(TaskAsyncHelper.Empty); bool isConnected = true; response.Setup(m => m.IsClientConnected).Returns(() => isConnected); response.Setup(m => m.Flush()).Returns(TaskAsyncHelper.Empty); var resolver = new DefaultDependencyResolver(); var config = resolver.Resolve<IConfigurationManager>(); var hostContext = new HostContext(request.Object, response.Object); config.DisconnectTimeout = TimeSpan.Zero; config.HeartbeatInterval = TimeSpan.FromSeconds(3); var transport = new Mock<ForeverTransport>(hostContext, resolver) { CallBase = true }; transport.Setup(m => m.Send(It.IsAny<PersistentResponse>())) .Returns(() => { var task = TaskAsyncHelper.FromError(new Exception()); isConnected = false; return task; }); var connectionManager = new ConnectionManager(resolver); var connection = connectionManager.GetConnection("Foo"); var wh = new ManualResetEventSlim(); transport.Object.ProcessRequest(connection).ContinueWith(task => { wh.Set(); }); connection.Broadcast("Some message"); Assert.True(wh.Wait(TimeSpan.FromSeconds(10))); }
public void SubscribingTopicAfterNoSubscriptionsStateSetsStateToHasSubscription() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); Topic topic = bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } }
public void MultipleSubscribeTopicCallsToDeadTopicWork() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); Topic topic; configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.KeepAlive = null; using (var bus = new TestMessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); int count = 0; // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); bus.BeforeTopicCreated = (key) => { bus.Topics.TryGetValue(key, out topic); if (count == 1) { // Should have been removed by our double garbage collect in BeforeTopicMarked Assert.Null(topic); } if (count == 3) { // Ensure that we have a topic now created from the original thread Assert.NotNull(topic); } }; bus.BeforeTopicMarked = (key, t) => { count++; if (count == 1) { bus.GarbageCollectTopics(); bus.GarbageCollectTopics(); // We garbage collect twice to mark the current topic as dead (it will remove it from the topics list) Assert.Equal(t.State, TopicState.Dead); bus.SubscribeTopic("key"); // Topic should still be dead Assert.Equal(t.State, TopicState.Dead); Assert.Equal(count, 2); // Increment up to 3 so we don't execute same code path in after marked count++; } if (count == 2) { // We've just re-created the topic from the second bus.SubscribeTopic so we should have 0 subscriptions Assert.Equal(t.State, TopicState.NoSubscriptions); } if (count == 4) { // Ensure that we pulled the already created subscription (therefore it has subscriptions) Assert.Equal(t.State, TopicState.HasSubscriptions); } }; bus.AfterTopicMarked = (key, t, state) => { if (count == 2) { // After re-creating the topic from the second bus.SubscribeTopic we should then move the topic state // into the has subscriptions state Assert.Equal(state, TopicState.HasSubscriptions); } if (count == 3) { Assert.Equal(state, TopicState.Dead); } }; bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } }
private static void RunConnectionTest() { string payload = GetPayload(); var dr = new DefaultDependencyResolver(); MeasureStats((MessageBus)dr.Resolve<IMessageBus>()); var connectionManager = new ConnectionManager(dr); var context = connectionManager.GetConnectionContext<StressConnection>(); for (int i = 0; i < _clients; i++) { ThreadPool.QueueUserWorkItem(state => { Interlocked.Increment(ref _clientsRunning); var transportConnection = (ITransportConnection)context.Connection; transportConnection.Receive(null, r => { Interlocked.Add(ref _received, r.TotalCount); Interlocked.Add(ref _avgLastReceivedCount, r.TotalCount); return TaskAsyncHelper.True; }, maxMessages: 10); }, i); } for (var i = 1; i <= _senders; i++) { ThreadPool.QueueUserWorkItem(_ => { StartSendLoop(i.ToString(), (source, key, value) => context.Connection.Broadcast(value), payload); }); } }
private static void RunConnectionReceiveLoopTest() { string payload = GetPayload(); var dr = new DefaultDependencyResolver(); MeasureStats((MessageBus)dr.Resolve<IMessageBus>()); var connectionManager = new ConnectionManager(dr); var context = connectionManager.GetConnectionContext<StressConnection>(); for (int i = 0; i < _clients; i++) { ThreadPool.QueueUserWorkItem(state => { Interlocked.Increment(ref _clientsRunning); var transportConnection = (ITransportConnection)context.Connection; ReceiveLoop(transportConnection, null); }, i); } for (var i = 1; i <= _senders; i++) { ThreadPool.QueueUserWorkItem(_ => { StartSendLoop(i.ToString(), (source, key, value) => context.Connection.Broadcast(value), payload); }); } }
public void GarbageCollectingTopicsAfterGettingTopicsNoops() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; bus.AfterTopicMarkedSuccessfully = (key, topic) => { bus.GarbageCollectTopics(); }; try { subscription = bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null); Assert.Equal(1, bus.Topics.Count); Topic topic; Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public PerformanceCounterManager(DefaultDependencyResolver resolver) : this(resolver.Resolve<ITraceManager>()) { }
public ServerNode(IMessageBus bus) { // Give each server it's own dependency resolver Server = new MemoryHost(); Connection = new FarmConnection(); Resolver = new DefaultDependencyResolver(); Resolver.Register(typeof(FarmConnection), () => Connection); Resolver.Register(typeof(IMessageBus), () => bus); var context = Resolver.Resolve<IConnectionManager>().GetConnectionContext<FarmConnection>(); _connection = context.Connection; }
public void SubscriptionGetsNewMessagesWhenTopicStoreOverrun() { var dr = new DefaultDependencyResolver(); dr.Resolve<IConfigurationManager>().DefaultMessageBufferSize = 10; using (var bus = new TestScaleoutBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; // 16-49 is the valid range var cd = new OrderedCountDownRange<int>(Enumerable.Range(16, 33)); var results = new List<bool>(); for (int i = 0; i < 50; i++) { bus.Publish(0, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } try { subscription = bus.Subscribe(subscriber, "s-0,1", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); cd.Expect(n); } return TaskAsyncHelper.True; }, 10, null); Assert.True(cd.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void PublishingDoesNotCreateTopic() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { bus.Publish("test", "key", "1").Wait(); Assert.Equal(0, bus.Topics.Count); Assert.False(bus.Topics.ContainsKey("key")); } }
public void GarbageCollectingTopicsBeforeSubscribingTopicSetsStateToHasSubscription() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { bus.BeforeTopicMarked = (key, t) => { bus.GarbageCollectTopics(); }; Topic topic = bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } }
public static void ConfigureRoutes(IAppBuilder app, IDependencyResolver resolver) { var hubConfig = new HubConfiguration { Resolver = resolver, EnableDetailedErrors = true }; app.MapSignalR(hubConfig); app.MapSignalR("/signalr2/test", new HubConfiguration() { Resolver = resolver }); var config = new ConnectionConfiguration { Resolver = resolver }; app.Map("/multisend", map => { map.UseCors(CorsOptions.AllowAll); map.RunSignalR<MySendingConnection>(config); }); app.Map("/autoencodedjson", map => { map.UseCors(CorsOptions.AllowAll); map.RunSignalR<EchoConnection>(config); }); app.Map("/redirectionConnection", map => { map.UseCors(CorsOptions.AllowAll); map.RunSignalR<RedirectionConnection>(config); }); app.Map("/statusCodeConnection", map => { map.UseCors(CorsOptions.AllowAll); map.RunSignalR<StatusCodeConnection>(config); }); app.Map("/jsonp", map => { var jsonpConfig = new ConnectionConfiguration { Resolver = resolver, EnableJSONP = true }; map.MapSignalR<EchoConnection>("/echo", jsonpConfig); var jsonpHubsConfig = new HubConfiguration { Resolver = resolver, EnableJSONP = true }; map.MapSignalR(jsonpHubsConfig); }); app.MapSignalR<MyBadConnection>("/ErrorsAreFun", config); app.MapSignalR<MyGroupEchoConnection>("/group-echo", config); app.MapSignalR<MyReconnect>("/my-reconnect", config); app.MapSignalR<ExamineHeadersConnection>("/examine-request", config); app.MapSignalR<ExamineReconnectPath>("/examine-reconnect", config); app.MapSignalR<MyGroupConnection>("/groups", config); app.MapSignalR<MyRejoinGroupsConnection>("/rejoin-groups", config); app.MapSignalR<BroadcastConnection>("/filter", config); app.MapSignalR<ConnectionThatUsesItems>("/items", config); app.MapSignalR<SyncErrorConnection>("/sync-error", config); app.MapSignalR<AddGroupOnConnectedConnection>("/add-group", config); app.MapSignalR<UnusableProtectedConnection>("/protected", config); app.MapSignalR<FallbackToLongPollingConnectionThrows>("/fall-back-throws", config); app.MapSignalR<PreserializedJsonConnection>("/preserialize", config); app.MapSignalR<AsyncOnConnectedConnection>("/async-on-connected", config); // This subpipeline is protected by basic auth app.Map("/basicauth", map => { map.Use(async (context, next) => { var authorization = context.Request.Headers.Get("Authorization"); if (string.IsNullOrEmpty(authorization)) { context.Response.StatusCode = 401; context.Response.Headers.Add("WWW-Authenticate", new string[] { "Basic" }); } else { var base64Encoded = authorization.Replace("Basic ", ""); byte[] base64EncodedBytes = Convert.FromBase64String(base64Encoded); var base64Decoded = System.Text.ASCIIEncoding.ASCII.GetString(base64EncodedBytes); var credentials = base64Decoded.Split(':'); var identity = new ClaimsIdentity("Basic"); identity.AddClaim(new Claim(ClaimTypes.Name, credentials[0])); context.Request.User = new ClaimsPrincipal(identity); await next(); } }); var subConfig = new ConnectionConfiguration { Resolver = resolver }; map.MapSignalR<AuthenticatedEchoConnection>("/echo", subConfig); var subHubsConfig = new HubConfiguration { Resolver = resolver }; map.MapSignalR(subHubsConfig); }); // This subpipeline is protected by cookie auth app.Map("/cookieauth", map => { var options = new CookieAuthenticationOptions() { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, LoginPath = CookieAuthenticationDefaults.LoginPath, LogoutPath = CookieAuthenticationDefaults.LogoutPath, }; map.UseCookieAuthentication(options); map.Use(async (context, next) => { if (context.Request.Path.Value.Contains(options.LoginPath.Value)) { if (context.Request.Method == "POST") { var form = await context.Request.ReadFormAsync(); var userName = form["UserName"]; var password = form["Password"]; var identity = new ClaimsIdentity(options.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name, userName)); context.Authentication.SignIn(identity); } } else { await next(); } }); var subConfig = new ConnectionConfiguration { Resolver = resolver }; map.MapSignalR<AuthenticatedEchoConnection>("/echo", subConfig); var subHubsConfig = new HubConfiguration { Resolver = resolver }; map.MapSignalR(subHubsConfig); }); app.Map("/fall-back", map => { map.Use((context, next) => { if (!context.Request.Path.Value.Contains("negotiate") && !context.Request.QueryString.Value.Contains("longPolling")) { context.Response.Body = new MemoryStream(); } return next(); }); map.RunSignalR<FallbackToLongPollingConnection>(); }); app.Map("/no-init", map => { map.Use((context, next) => { if (context.Request.Path.Value.Contains("connect")) { context.Response.Body = new MemoryStream(); } return next(); }); }); app.Map("/force-lp-reconnect", map => { map.Use((context, next) => { if (context.Request.Path.Value.Contains("poll")) { context.Response.StatusCode = 500; return TaskAsyncHelper.Empty; } return next(); }); map.MapSignalR<ExamineReconnectPath>("/examine-reconnect", config); map.MapSignalR(hubConfig); }); var longPollDelayResolver = new DefaultDependencyResolver(); var configManager = longPollDelayResolver.Resolve<IConfigurationManager>(); configManager.LongPollDelay = TimeSpan.FromSeconds(60); // Make the disconnect timeout and the keep alive interval short so we can // complete our tests quicker. configManager.DisconnectTimeout = TimeSpan.FromSeconds(6); app.MapSignalR<EchoConnection>("/longPollDelay", new ConnectionConfiguration { Resolver = longPollDelayResolver }); // Perf/stress test related var performanceConfig = new ConnectionConfiguration { Resolver = resolver }; app.MapSignalR<StressConnection>("/echo", performanceConfig); performanceConfig.Resolver.Register(typeof(IProtectedData), () => new EmptyProtectedData()); // IMPORTANT: This needs to run last so that it runs in the "default" part of the pipeline // Session is enabled for ASP.NET on the session path app.Map("/session", map => { map.MapSignalR(); }); }
public void GetTopicDoesNotChangeStateWhenNotDying() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { bus.Subscribe(new TestSubscriber(new[] { "key" }), null, (result, state) => TaskAsyncHelper.True, 10, null); Topic topic; Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); topic = bus.GetTopic("key"); Assert.Equal(TopicState.HasSubscriptions, topic.State); topic.RemoveSubscription(topic.Subscriptions.First()); Assert.Equal(TopicState.NoSubscriptions, topic.State); topic = bus.GetTopic("key"); Assert.Equal(TopicState.NoSubscriptions, topic.State); topic.State = TopicState.Dying; topic = bus.GetTopic("key"); Assert.Equal(TopicState.NoSubscriptions, topic.State); } }
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))); } } }