コード例 #1
0
        public async Task FarmDisconnectRaisesUncleanDisconnects()
        {
            EnableTracing();

            // Each node shares the same bus but are indepenent servers
            var counters             = new SignalR.Infrastructure.PerformanceCounterManager();
            var configurationManager = new DefaultConfigurationManager();
            var protectedData        = new DefaultProtectedData();

            using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000))
            {
                var nodeCount = 3;
                var nodes     = new List <ServerNode>();
                for (int i = 0; i < nodeCount; i++)
                {
                    nodes.Add(new ServerNode(bus));
                }

                var timeout = TimeSpan.FromSeconds(5);
                foreach (var node in nodes)
                {
                    var config = node.Resolver.Resolve <IConfigurationManager>();
                    config.DisconnectTimeout = TimeSpan.FromSeconds(6);

                    IDependencyResolver resolver = node.Resolver;
                    node.Server.Configure(app =>
                    {
                        app.MapSignalR <FarmConnection>("/echo", new ConnectionConfiguration
                        {
                            Resolver = resolver
                        });

                        resolver.Register(typeof(IProtectedData), () => protectedData);
                    });
                }

                var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray());
                var transport    = new Client.Transports.LongPollingTransport(loadBalancer);

                var connection = new Client.Connection("http://goo/echo");

                await connection.Start(transport);

                for (int i = 0; i < nodes.Count; i++)
                {
                    nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1));
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }

                ((Client.IConnection)connection).Disconnect();

                await Task.Delay(TimeSpan.FromTicks(timeout.Ticks *nodes.Count));

                Assert.Equal(0, FarmConnection.CleanDisconnectCount);
                Assert.Equal(3, FarmConnection.UncleanDisconnectCount);
            }
        }
コード例 #2
0
ファイル: DisconnectFacts.cs プロジェクト: zhang024/SignalR
        public void FarmDisconnectOnlyRaisesEventOnce()
        {
            EnableTracing();

            // Each node shares the same bus but are indepenent servers
            var counters             = new SignalR.Infrastructure.PerformanceCounterManager();
            var configurationManager = new DefaultConfigurationManager();

            using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000))
            {
                var nodeCount = 3;
                var nodes     = new List <ServerNode>();
                for (int i = 0; i < nodeCount; i++)
                {
                    nodes.Add(new ServerNode(bus));
                }

                var timeout = TimeSpan.FromSeconds(5);
                foreach (var node in nodes)
                {
                    var config = node.Resolver.Resolve <IConfigurationManager>();
                    config.DisconnectTimeout = TimeSpan.FromSeconds(6);

                    IDependencyResolver resolver = node.Resolver;
                    node.Server.Configure(app =>
                    {
                        app.MapConnection <FarmConnection>("/echo", new ConnectionConfiguration
                        {
                            Resolver = resolver
                        });
                    });
                }

                var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray());
                var transport    = new Client.Transports.LongPollingTransport(loadBalancer);

                var connection = new Client.Connection("http://goo/echo");

                connection.Start(transport).Wait();

                for (int i = 0; i < nodes.Count; i++)
                {
                    nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1));
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }

                ((Client.IConnection)connection).Disconnect();

                Thread.Sleep(TimeSpan.FromTicks(timeout.Ticks * nodes.Count));

                Assert.Equal(1, nodes.Sum(n => n.Connection.DisconnectCount));
            }
        }
コード例 #3
0
ファイル: FarmFacts.cs プロジェクト: xxlllq/SignalR
        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);
                    }
        }
コード例 #4
0
ファイル: FarmFacts.cs プロジェクト: kietnha/SignalR
        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);
            }
        }
コード例 #5
0
            public void GroupsAreNotReadOnConnectedAsyncLongPolling()
            {
                var host = new MemoryHost();
                host.MapConnection<MyConnection>("/echo");

                var connection = new Client.Connection("http://foo/echo");
                connection.Groups = new List<string> { typeof(MyConnection).FullName + ".test" };
                connection.Received += data =>
                {
                    Assert.False(true, "Unexpectedly received data");
                };

                var transport = new Client.Transports.LongPollingTransport(host);
                connection.Start(transport).Wait();

                Thread.Sleep(TimeSpan.FromSeconds(10));
            }
コード例 #6
0
        public void FarmDisconnectOnlyRaisesEventOnce()
        {
            // Each node shares the same bus but are indepenent servers
            var counters  = new SignalR.Infrastructure.PerformanceCounterManager();
            var bus       = new MessageBus(new TraceManager(), counters);
            var nodeCount = 3;
            var nodes     = new List <ServerNode>();

            for (int i = 0; i < nodeCount; i++)
            {
                nodes.Add(new ServerNode(bus));
            }

            var timeout = TimeSpan.FromSeconds(5);

            foreach (var node in nodes)
            {
                node.Server.Configuration.HeartBeatInterval = timeout;
                node.Server.Configuration.DisconnectTimeout = TimeSpan.Zero;
                node.Server.MapConnection <FarmConnection>("/echo");
            }

            var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray());
            var transport    = new Client.Transports.LongPollingTransport(loadBalancer);

            var connection = new Client.Connection("http://goo/echo");

            connection.Start(transport).Wait();

            for (int i = 0; i < nodes.Count; i++)
            {
                nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1));
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }

            connection.Stop();

            Thread.Sleep(TimeSpan.FromTicks(timeout.Ticks * nodes.Count));

            Assert.Equal(1, nodes.Sum(n => n.Connection.DisconnectCount));
        }
コード例 #7
0
            public void GroupsAreNotReadOnConnectedAsyncLongPolling()
            {
                using (var host = new MemoryHost())
                {
                    host.MapConnection <MyConnection>("/echo");

                    var connection = new Client.Connection("http://foo/echo");
                    connection.Groups = new List <string> {
                        typeof(MyConnection).FullName + ".test"
                    };
                    connection.Received += data =>
                    {
                        Assert.False(true, "Unexpectedly received data");
                    };

                    var transport = new Client.Transports.LongPollingTransport(host);
                    connection.Start(transport).Wait();

                    Thread.Sleep(TimeSpan.FromSeconds(5));

                    connection.Stop();
                }
            }
コード例 #8
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();
                    }
        }
コード例 #9
0
        public async Task FarmGroupAddCompletesSuccessfully(TransportType transportType)
        {
            // https://github.com/SignalR/SignalR/issues/3337
            // Each node shares the same bus but are independent servers
            const int nodeCount            = 2;
            var       counters             = new PerformanceCounterManager();
            var       configurationManager = new DefaultConfigurationManager();

            // Ensure /send and /connect requests get handled by different servers
            Func <string, int> scheduler = url => url.Contains("/send") ? 0 : 1;

            using (EnableTracing())
                using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000))
                    using (var loadBalancer = new LoadBalancer(nodeCount, scheduler))
                    {
                        loadBalancer.Configure(app =>
                        {
                            var resolver = new DefaultDependencyResolver();
                            resolver.Register(typeof(IMessageBus), () => bus);
                            app.MapSignalR(new HubConfiguration {
                                Resolver = resolver
                            });
                        });

                        using (var connection = new HubConnection("http://goo/"))
                        {
                            var proxy = connection.CreateHubProxy("FarmGroupHub");

                            const string group   = "group";
                            const string message = "message";

                            var mre = new AsyncManualResetEvent();
                            proxy.On <string>("message", m =>
                            {
                                if (m == message)
                                {
                                    mre.Set();
                                }
                            });

                            Client.Transports.IClientTransport transport;

                            switch (transportType)
                            {
                            case TransportType.LongPolling:
                                transport = new Client.Transports.LongPollingTransport(loadBalancer);
                                break;

                            case TransportType.ServerSentEvents:
                                transport = new Client.Transports.ServerSentEventsTransport(loadBalancer);
                                break;

                            default:
                                throw new ArgumentException("transportType");
                            }

                            await connection.Start(transport);

                            await proxy.Invoke("JoinGroup", group);

                            await proxy.Invoke("SendToGroup", group, message);

                            Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5)));
                        }
                    }
        }
コード例 #10
0
ファイル: DisconnectFacts.cs プロジェクト: paulduran/SignalR
        public void FarmDisconnectOnlyRaisesEventOnce()
        {
            // Each node shares the same bus but are indepenent servers
            var bus = new InProcessMessageBus(new TraceManager(), garbageCollectMessages: false);
            var nodeCount = 3;
            var nodes = new List<ServerNode>();
            for (int i = 0; i < nodeCount; i++)
            {
                nodes.Add(new ServerNode(bus));
            }

            var timeout = TimeSpan.FromSeconds(5);
            foreach (var node in nodes)
            {
                node.Server.Configuration.HeartBeatInterval = timeout;
                node.Server.Configuration.DisconnectTimeout = TimeSpan.Zero;
                node.Server.MapConnection<FarmConnection>("/echo");
            }

            var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray());
            var transport = new Client.Transports.LongPollingTransport(loadBalancer);

            var connection = new Client.Connection("http://goo/echo");

            connection.Start(transport).Wait();

            for (int i = 0; i < nodes.Count; i++)
            {
                nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1));
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }

            Thread.Sleep(TimeSpan.FromTicks(timeout.Ticks * nodes.Count));

            Assert.Equal(1, nodes.Sum(n => n.Connection.DisconnectCount));
        }
コード例 #11
0
ファイル: FarmFacts.cs プロジェクト: kietnha/SignalR
        public async Task FarmGroupAddCompletesSuccessfully(TransportType transportType)
        {
            // https://github.com/SignalR/SignalR/issues/3337
            // Each node shares the same bus but are independent servers
            const int nodeCount = 2;
            var counters = new Infrastructure.PerformanceCounterManager();
            var configurationManager = new DefaultConfigurationManager();

            // Ensure /send and /connect requests get handled by different servers
            Func<string, int> scheduler = url => url.Contains("/send") ? 0 : 1;

            using (EnableDisposableTracing())
            using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000))
            using (var loadBalancer = new LoadBalancer(nodeCount, scheduler))
            {
                loadBalancer.Configure(app =>
                {
                    var resolver = new DefaultDependencyResolver();
                    resolver.Register(typeof(IMessageBus), () => bus);
                    app.MapSignalR(new HubConfiguration { Resolver = resolver });
                });

                using (var connection = new HubConnection("http://goo/"))
                {
                    var proxy = connection.CreateHubProxy("FarmGroupHub");

                    const string group = "group";
                    const string message = "message";

                    var mre = new AsyncManualResetEvent();
                    proxy.On<string>("message", m =>
                    {
                        if (m == message)
                        {
                            mre.Set();
                        }
                    });

                    Client.Transports.IClientTransport transport;

                    switch (transportType)
                    {
                        case TransportType.LongPolling:
                            transport = new Client.Transports.LongPollingTransport(loadBalancer);
                            break;
                        case TransportType.ServerSentEvents:
                            transport = new Client.Transports.ServerSentEventsTransport(loadBalancer);
                            break;
                        default:
                            throw new ArgumentException("transportType");
                    }

                    await connection.Start(transport);

                    await proxy.Invoke("JoinGroup", group);
                    await proxy.Invoke("SendToGroup", group, message);

                    Assert.True(await mre.WaitAsync(TimeSpan.FromSeconds(5)));
                }
            }
        }
コード例 #12
0
        public async Task FarmDisconnectOnlyRaisesUncleanDisconnects()
        {
            EnableTracing();

            // Each node shares the same bus but are indepenent servers
            var counters = new SignalR.Infrastructure.PerformanceCounterManager();
            var configurationManager = new DefaultConfigurationManager();
            var protectedData = new DefaultProtectedData();
            using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000))
            {
                var nodeCount = 3;
                var nodes = new List<ServerNode>();
                for (int i = 0; i < nodeCount; i++)
                {
                    nodes.Add(new ServerNode(bus));
                }

                var timeout = TimeSpan.FromSeconds(5);
                foreach (var node in nodes)
                {
                    var config = node.Resolver.Resolve<IConfigurationManager>();
                    config.DisconnectTimeout = TimeSpan.FromSeconds(6);

                    IDependencyResolver resolver = node.Resolver;
                    node.Server.Configure(app =>
                    {
                        app.MapSignalR<FarmConnection>("/echo", new ConnectionConfiguration
                        {
                            Resolver = resolver
                        });

                        resolver.Register(typeof(IProtectedData), () => protectedData);
                    });
                }

                var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray());
                var transport = new Client.Transports.LongPollingTransport(loadBalancer);

                var connection = new Client.Connection("http://goo/echo");

                await connection.Start(transport);

                for (int i = 0; i < nodes.Count; i++)
                {
                    nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1));
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }

                ((Client.IConnection)connection).Disconnect();

                await Task.Delay(TimeSpan.FromTicks(timeout.Ticks * nodes.Count));

                Assert.Equal(0, FarmConnection.OldOnDisconnectedCalls);
                Assert.Equal(0, FarmConnection.CleanDisconnectCount);
                Assert.Equal(3, FarmConnection.UncleanDisconnectCount);
            }
        }
コード例 #13
0
ファイル: DisconnectFacts.cs プロジェクト: stirno/SignalR
        public void FarmDisconnectOnlyRaisesEventOnce()
        {
            // Each node shares the same bus but are indepenent servers
            var counters = new SignalR.Infrastructure.PerformanceCounterManager();
            var configurationManager = new DefaultConfigurationManager();
            using (var bus = new MessageBus(new StringMinifier(), new TraceManager(), counters, configurationManager, 5000))
            {
                var nodeCount = 3;
                var nodes = new List<ServerNode>();
                for (int i = 0; i < nodeCount; i++)
                {
                    nodes.Add(new ServerNode(bus));
                }

                var timeout = TimeSpan.FromSeconds(5);
                foreach (var node in nodes)
                {
                    var config = node.Resolver.Resolve<IConfigurationManager>();
                    config.DisconnectTimeout = TimeSpan.FromSeconds(6);

                    IDependencyResolver resolver = node.Resolver;
                    node.Server.Configure(app =>
                    {
                        app.MapConnection<FarmConnection>("/echo", new ConnectionConfiguration
                        {
                            Resolver = resolver
                        });
                    });
                }

                var loadBalancer = new LoadBalancer(nodes.Select(f => f.Server).ToArray());
                var transport = new Client.Transports.LongPollingTransport(loadBalancer);

                var connection = new Client.Connection("http://goo/echo");

                connection.Start(transport).Wait();

                for (int i = 0; i < nodes.Count; i++)
                {
                    nodes[i].Broadcast(String.Format("From Node {0}: {1}", i, i + 1));
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }

                connection.Disconnect();

                Thread.Sleep(TimeSpan.FromTicks(timeout.Ticks * nodes.Count));

                Assert.Equal(1, nodes.Sum(n => n.Connection.DisconnectCount));
            }
        }