Beispiel #1
0
        public async Task StillSubscribedToUserAfterOneOfMultipleConnectionsAssociatedWithUserDisconnects()
        {
            var server = new TestRedisServer();

            var manager = CreateLifetimeManager(server);

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                    using (var client3 = new TestClient())
                    {
                        var connection1 = HubConnectionContextUtils.Create(client1.Connection, userIdentifier: "userA");
                        var connection2 = HubConnectionContextUtils.Create(client2.Connection, userIdentifier: "userA");
                        var connection3 = HubConnectionContextUtils.Create(client3.Connection, userIdentifier: "userB");

                        await manager.OnConnectedAsync(connection1).OrTimeout();

                        await manager.OnConnectedAsync(connection2).OrTimeout();

                        await manager.OnConnectedAsync(connection3).OrTimeout();

                        await manager.SendUserAsync("userA", "Hello", new object[] { "World" }).OrTimeout();
                        await AssertMessageAsync(client1);
                        await AssertMessageAsync(client2);

                        // Disconnect one connection for the user
                        await manager.OnDisconnectedAsync(connection1).OrTimeout();

                        await manager.SendUserAsync("userA", "Hello", new object[] { "World" }).OrTimeout();
                        await AssertMessageAsync(client2);
                    }
        }
        public async Task InvokeAllAsyncWithMultipleServersDoesNotWriteToDisconnectedConnectionsOutput()
        {
            var server = new TestRedisServer();

            var manager1 = CreateLifetimeManager(server);
            var manager2 = CreateLifetimeManager(server);

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager1.OnConnectedAsync(connection1).OrTimeout();

                    await manager2.OnConnectedAsync(connection2).OrTimeout();

                    await manager2.OnDisconnectedAsync(connection2).OrTimeout();

                    await manager2.SendAllAsync("Hello", new object[] { "World" }).OrTimeout();

                    await AssertMessageAsync(client1);

                    Assert.Null(client2.TryRead());
                }
        }
        public async Task InvokeAllExceptAsyncExcludesSpecifiedConnections()
        {
            var server = new TestRedisServer();

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                    using (var client3 = new TestClient())
                    {
                        var manager1 = CreateLifetimeManager(server);
                        var manager2 = CreateLifetimeManager(server);
                        var manager3 = CreateLifetimeManager(server);

                        var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                        var connection2 = HubConnectionContextUtils.Create(client2.Connection);
                        var connection3 = HubConnectionContextUtils.Create(client3.Connection);

                        await manager1.OnConnectedAsync(connection1).OrTimeout();

                        await manager2.OnConnectedAsync(connection2).OrTimeout();

                        await manager3.OnConnectedAsync(connection3).OrTimeout();

                        await manager1.SendAllExceptAsync("Hello", new object[] { "World" }, new [] { client3.Connection.ConnectionId }).OrTimeout();

                        await AssertMessageAsync(client1);
                        await AssertMessageAsync(client2);

                        Assert.Null(client3.TryRead());
                    }
        }
Beispiel #4
0
        // Re-enable micro-benchmark when https://github.com/aspnet/SignalR/issues/3088 is fixed
        // [GlobalSetup]
        public void GlobalSetup()
        {
            var server    = new TestRedisServer();
            var logger    = NullLogger <RedisHubLifetimeManager <TestHub> > .Instance;
            var protocols = GenerateProtocols(ProtocolCount).ToArray();
            var options   = Options.Create(new RedisOptions()
            {
                ConnectionFactory = _ => Task.FromResult <IConnectionMultiplexer>(new TestConnectionMultiplexer(server))
            });
            var resolver = new DefaultHubProtocolResolver(protocols, NullLogger <DefaultHubProtocolResolver> .Instance);

            _manager1 = new RedisHubLifetimeManager <TestHub>(logger, options, resolver);
            _manager2 = new RedisHubLifetimeManager <TestHub>(logger, options, resolver);

            async Task ConnectClient(TestClient client, IHubProtocol protocol, string userId, string groupName)
            {
                await _manager2.OnConnectedAsync(HubConnectionContextUtils.Create(client.Connection, protocol, userId));

                await _manager2.AddToGroupAsync(client.Connection.ConnectionId, "Everyone");

                await _manager2.AddToGroupAsync(client.Connection.ConnectionId, groupName);
            }

            // Connect clients
            _clients = new TestClient[ClientCount];
            var tasks = new Task[ClientCount];

            for (var i = 0; i < _clients.Length; i++)
            {
                var protocol = protocols[i % ProtocolCount];
                _clients[i] = new TestClient(protocol: protocol);

                string group;
                string user;
                if ((i % 2) == 0)
                {
                    group = "Evens";
                    user  = "******";
                    _excludedConnectionIds.Add(_clients[i].Connection.ConnectionId);
                }
                else
                {
                    group = "Odds";
                    user  = "******";
                    _sendIds.Add(_clients[i].Connection.ConnectionId);
                }

                tasks[i] = ConnectClient(_clients[i], protocol, user, group);
                _        = ConsumeAsync(_clients[i]);
            }

            Task.WaitAll(tasks);

            _groups.Add("Evens");
            _groups.Add("Odds");
            _users.Add("EvenUser");
            _users.Add("OddUser");

            _args = new object[] { "Foo" };
        }
        public async Task RemoveGroupAsyncForConnectionOnDifferentServerWorks()
        {
            var server = new TestRedisServer();

            var manager1 = CreateLifetimeManager(server);
            var manager2 = CreateLifetimeManager(server);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager1.OnConnectedAsync(connection).OrTimeout();

                await manager1.AddGroupAsync(connection.ConnectionId, "name").OrTimeout();

                await manager2.SendGroupAsync("name", "Hello", new object[] { "World" }).OrTimeout();

                await AssertMessageAsync(client);

                await manager2.RemoveGroupAsync(connection.ConnectionId, "name").OrTimeout();

                await manager2.SendGroupAsync("name", "Hello", new object[] { "World" }).OrTimeout();

                Assert.Null(client.TryRead());
            }
        }
        public async Task WritingToGroupWithOneConnectionFailingSecondConnectionStillReceivesMessage()
        {
            var server = new TestRedisServer();

            var manager = CreateLifetimeManager(server);

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    // Force an exception when writing to connection
                    var connectionMock = HubConnectionContextUtils.CreateMock(client1.Connection);
                    connectionMock.Setup(m => m.WriteAsync(It.IsAny <HubMessage>())).Throws(new Exception());

                    var connection1 = connectionMock.Object;
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager.OnConnectedAsync(connection1).OrTimeout();

                    await manager.AddGroupAsync(connection1.ConnectionId, "group");

                    await manager.OnConnectedAsync(connection2).OrTimeout();

                    await manager.AddGroupAsync(connection2.ConnectionId, "group");

                    await manager.SendGroupAsync("group", "Hello", new object[] { "World" }).OrTimeout();

                    // connection1 will throw when receiving a group message, we are making sure other connections
                    // are not affected by another connection throwing
                    await AssertMessageAsync(client2);

                    // Repeat to check that group can still be sent to
                    await manager.SendGroupAsync("group", "Hello", new object[] { "World" }).OrTimeout();
                    await AssertMessageAsync(client2);
                }
        }
        public async Task InvokeConnectionAsyncOnNonExistentConnectionDoesNotThrow()
        {
            var server = new TestRedisServer();

            var manager = CreateLifetimeManager(server);
            await manager.SendConnectionAsync("NotARealConnectionId", "Hello", new object[] { "World" }).OrTimeout();
        }
Beispiel #8
0
        public async Task XmlRoundTripsToActualRedisServer()
        {
            var connStr = TestRedisServer.GetConnectionString();

            _output.WriteLine("Attempting to connect to " + connStr);

            var      guid = Guid.NewGuid().ToString();
            RedisKey key  = "Test:DP:Key" + guid;

            try
            {
                using (var redis = await ConnectionMultiplexer.ConnectAsync(connStr).TimeoutAfter(TimeSpan.FromMinutes(1)))
                {
                    var repo    = new RedisXmlRepository(() => redis.GetDatabase(), key);
                    var element = new XElement("HelloRedis", guid);
                    repo.StoreElement(element, guid);
                }

                using (var redis = await ConnectionMultiplexer.ConnectAsync(connStr).TimeoutAfter(TimeSpan.FromMinutes(1)))
                {
                    var repo     = new RedisXmlRepository(() => redis.GetDatabase(), key);
                    var elements = repo.GetAllElements();

                    Assert.Contains(elements, e => e.Name == "HelloRedis" && e.Value == guid);
                }
            }
            finally
            {
                // cleanup
                using (var redis = await ConnectionMultiplexer.ConnectAsync(connStr).TimeoutAfter(TimeSpan.FromMinutes(1)))
                {
                    await redis.GetDatabase().KeyDeleteAsync(key);
                }
            }
        }
Beispiel #9
0
        public async Task InvokeUserSendsToAllConnectionsForUser()
        {
            var server = new TestRedisServer();

            var manager = CreateLifetimeManager(server);

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                    using (var client3 = new TestClient())
                    {
                        var connection1 = HubConnectionContextUtils.Create(client1.Connection, userIdentifier: "userA");
                        var connection2 = HubConnectionContextUtils.Create(client2.Connection, userIdentifier: "userA");
                        var connection3 = HubConnectionContextUtils.Create(client3.Connection, userIdentifier: "userB");

                        await manager.OnConnectedAsync(connection1).OrTimeout();

                        await manager.OnConnectedAsync(connection2).OrTimeout();

                        await manager.OnConnectedAsync(connection3).OrTimeout();

                        await manager.SendUserAsync("userA", "Hello", new object[] { "World" }).OrTimeout();
                        await AssertMessageAsync(client1);
                        await AssertMessageAsync(client2);
                    }
        }
        public async Task InvokeGroupExceptAsyncWritesToAllValidConnectionsInGroupOutput()
        {
            var server = new TestRedisServer();

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    var manager     = CreateLifetimeManager(server);
                    var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager.OnConnectedAsync(connection1).OrTimeout();

                    await manager.OnConnectedAsync(connection2).OrTimeout();

                    await manager.AddGroupAsync(connection1.ConnectionId, "gunit").OrTimeout();

                    await manager.AddGroupAsync(connection2.ConnectionId, "gunit").OrTimeout();

                    var excludedIds = new List <string> {
                        client2.Connection.ConnectionId
                    };
                    await manager.SendGroupExceptAsync("gunit", "Hello", new object[] { "World" }, excludedIds).OrTimeout();

                    await AssertMessageAsync(client1);

                    Assert.Null(client2.TryRead());
                }
        }
        public async Task RemoveGroupFromLocalConnectionNotInGroupDoesNothing()
        {
            var server = new TestRedisServer();

            var manager = CreateLifetimeManager(server);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager.OnConnectedAsync(connection).OrTimeout();

                await manager.RemoveGroupAsync(connection.ConnectionId, "name").OrTimeout();
            }
        }
        public async Task CamelCasedJsonIsPreservedAcrossRedisBoundary()
        {
            var server = new TestRedisServer();

            var messagePackOptions = new MessagePackHubProtocolOptions();

            messagePackOptions.SerializationContext.DictionarySerlaizationOptions.KeyTransformer = DictionaryKeyTransformers.LowerCamel;

            var jsonOptions = new JsonHubProtocolOptions();

            jsonOptions.PayloadSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    // The sending manager has serializer settings
                    var manager1 = CreateLifetimeManager(server, messagePackOptions, jsonOptions);

                    // The receiving one doesn't matter because of how we serialize!
                    var manager2 = CreateLifetimeManager(server);

                    var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager1.OnConnectedAsync(connection1).OrTimeout();

                    await manager2.OnConnectedAsync(connection2).OrTimeout();

                    await manager1.SendAllAsync("Hello", new object[] { new TestObject {
                                                                            TestProperty = "Foo"
                                                                        } });

                    var message = Assert.IsType <InvocationMessage>(await client2.ReadAsync().OrTimeout());
                    Assert.Equal("Hello", message.Target);
                    Assert.Collection(
                        message.Arguments,
                        arg0 =>
                    {
                        var dict = Assert.IsType <JObject>(arg0);
                        Assert.Collection(dict.Properties(),
                                          prop =>
                        {
                            Assert.Equal("testProperty", prop.Name);
                            Assert.Equal("Foo", prop.Value.Value <string>());
                        });
                    });
                }
        }
        public async Task InvokeConnectionAsyncWritesToConnectionOutput()
        {
            var server = new TestRedisServer();

            using (var client = new TestClient())
            {
                var manager    = CreateLifetimeManager(server);
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager.OnConnectedAsync(connection).OrTimeout();

                await manager.SendConnectionAsync(connection.ConnectionId, "Hello", new object[] { "World" }).OrTimeout();

                await AssertMessageAsync(client);
            }
        }
        private RedisHubLifetimeManager <MyHub> CreateLifetimeManager(TestRedisServer server, MessagePackHubProtocolOptions messagePackOptions = null, JsonHubProtocolOptions jsonOptions = null)
        {
            var options = new RedisOptions()
            {
                ConnectionFactory = async(t) => await Task.FromResult(new TestConnectionMultiplexer(server))
            };

            messagePackOptions = messagePackOptions ?? new MessagePackHubProtocolOptions();
            jsonOptions        = jsonOptions ?? new JsonHubProtocolOptions();
            return(new RedisHubLifetimeManager <MyHub>(
                       NullLogger <RedisHubLifetimeManager <MyHub> > .Instance,
                       Options.Create(options),
                       new DefaultHubProtocolResolver(new IHubProtocol[]
            {
                new JsonHubProtocol(Options.Create(jsonOptions)),
                new MessagePackHubProtocol(Options.Create(messagePackOptions)),
            }, NullLogger <DefaultHubProtocolResolver> .Instance)));
        }
        public async Task InvokeGroupAsyncOnServerWithoutConnectionWritesOutputToGroupConnection()
        {
            var server = new TestRedisServer();

            var manager1 = CreateLifetimeManager(server);
            var manager2 = CreateLifetimeManager(server);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager1.OnConnectedAsync(connection).OrTimeout();

                await manager1.AddGroupAsync(connection.ConnectionId, "name").OrTimeout();

                await manager2.SendGroupAsync("name", "Hello", new object[] { "World" }).OrTimeout();

                await AssertMessageAsync(client);
            }
        }
        public async Task InvokeAllAsyncWritesToAllConnectionsOutput()
        {
            var server = new TestRedisServer();

            using (var client1 = new TestClient())
                using (var client2 = new TestClient())
                {
                    var manager     = CreateLifetimeManager(server);
                    var connection1 = HubConnectionContextUtils.Create(client1.Connection);
                    var connection2 = HubConnectionContextUtils.Create(client2.Connection);

                    await manager.OnConnectedAsync(connection1).OrTimeout();

                    await manager.OnConnectedAsync(connection2).OrTimeout();

                    await manager.SendAllAsync("Hello", new object[] { "World" }).OrTimeout();

                    await AssertMessageAsync(client1);
                    await AssertMessageAsync(client2);
                }
        }
        public async Task WritingToRemoteConnectionThatFailsDoesNotThrow()
        {
            var server = new TestRedisServer();

            var manager1 = CreateLifetimeManager(server);
            var manager2 = CreateLifetimeManager(server);

            using (var client = new TestClient())
            {
                // Force an exception when writing to connection
                var connectionMock = HubConnectionContextUtils.CreateMock(client.Connection);
                connectionMock.Setup(m => m.WriteAsync(It.IsAny <HubMessage>())).Throws(new Exception());
                var connection = connectionMock.Object;

                await manager2.OnConnectedAsync(connection).OrTimeout();

                // This doesn't throw because there is no connection.ConnectionId on this server so it has to publish to redis.
                // And once that happens there is no way to know if the invocation was successful or not.
                await manager1.SendConnectionAsync(connection.ConnectionId, "Hello", new object[] { "World" }).OrTimeout();
            }
        }
        public async Task DisconnectConnectionRemovesConnectionFromGroup()
        {
            var server = new TestRedisServer();

            var manager = CreateLifetimeManager(server);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager.OnConnectedAsync(connection).OrTimeout();

                await manager.AddGroupAsync(connection.ConnectionId, "name").OrTimeout();

                await manager.OnDisconnectedAsync(connection).OrTimeout();

                await manager.SendGroupAsync("name", "Hello", new object[] { "World" }).OrTimeout();

                Assert.Null(client.TryRead());
            }
        }
        public async Task AddGroupAsyncForLocalConnectionAlreadyInGroupDoesNothing()
        {
            var server = new TestRedisServer();

            var manager = CreateLifetimeManager(server);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                await manager.OnConnectedAsync(connection).OrTimeout();

                await manager.AddGroupAsync(connection.ConnectionId, "name").OrTimeout();

                await manager.AddGroupAsync(connection.ConnectionId, "name").OrTimeout();

                await manager.SendGroupAsync("name", "Hello", new object[] { "World" }).OrTimeout();

                await AssertMessageAsync(client);

                Assert.Null(client.TryRead());
            }
        }
        public async Task InvokeConnectionAsyncForLocalConnectionDoesNotPublishToRedis()
        {
            var server = new TestRedisServer();

            var manager1 = CreateLifetimeManager(server);
            var manager2 = CreateLifetimeManager(server);

            using (var client = new TestClient())
            {
                var connection = HubConnectionContextUtils.Create(client.Connection);

                // Add connection to both "servers" to see if connection receives message twice
                await manager1.OnConnectedAsync(connection).OrTimeout();

                await manager2.OnConnectedAsync(connection).OrTimeout();

                await manager1.SendConnectionAsync(connection.ConnectionId, "Hello", new object[] { "World" }).OrTimeout();

                await AssertMessageAsync(client);

                Assert.Null(client.TryRead());
            }
        }
 public TestSubscriber(TestRedisServer server)
 {
     _server = server;
 }
 public TestSubscriber(TestRedisServer server)
 {
     _server = server;
     _id     = Interlocked.Increment(ref StaticId);
 }