Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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");
            }
        }
Пример #5
0
        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));
            }
        }
Пример #6
0
        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;
        }
Пример #7
0
        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();
                    }
                }
            }
        }
Пример #8
0
        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);
                });
            }
        }
Пример #9
0
        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);
                });
            }
        }
Пример #10
0
        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();
                    }
                }
            }
        }
Пример #13
0
        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);
        }
Пример #15
0
        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);
            });
        }
Пример #16
0
        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);
        }
Пример #17
0
        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));
        }
Пример #19
0
        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>());
        }
Пример #20
0
        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)));
                        }
                    }
        }
Пример #21
0
        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);
                    }
        }
Пример #22
0
        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));
        }
Пример #24
0
        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));
        }
Пример #26
0
        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
                });
            }
            ;
        }
Пример #27
0
        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"));
            }
        }
Пример #28
0
        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();
                    }
                }
            }
        }
Пример #30
0
        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));
        }
Пример #32
0
        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);
            }
        }
Пример #33
0
        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);
            }
        }
Пример #34
0
        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");
            }
        }
Пример #35
0
        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);
            }
        }
Пример #36
0
        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");
            }
        }
Пример #37
0
        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");
            }
        }
Пример #38
0
        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");
            }
        }
Пример #39
0
        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();
                    }
        }
Пример #40
0
        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);
            });
        }
Пример #41
0
        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");
            }
        }
Пример #42
0
        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)));
        }
Пример #43
0
        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);
            }
        }
Пример #44
0
        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);
            }
        }
Пример #45
0
        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);
                });
            }
        }
Пример #46
0
        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);
                });
            }
        }
Пример #47
0
        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>())
        {

        }
Пример #49
0
            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();
                    }
                }
            }
        }
Пример #51
0
        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"));
            }
        }
Пример #52
0
        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);
            }
        }
Пример #53
0
        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();
            });
        }
Пример #54
0
        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);
            }
        }
Пример #55
0
        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)));
                }
            }
        }