Пример #1
0
        public async Task CloseClientsWhenReceiveInstanceOfflinePing()
        {
            // Prepare clients
            var instanceId1   = Guid.NewGuid().ToString();
            var connectionId1 = Guid.NewGuid().ToString("N");
            var header1       = new HeaderDictionary()
            {
                { Constants.AsrsInstanceId, instanceId1 }
            };

            var instanceId2   = Guid.NewGuid().ToString();
            var connectionId2 = Guid.NewGuid().ToString("N");
            var header2       = new HeaderDictionary()
            {
                { Constants.AsrsInstanceId, instanceId2 }
            };

            var proxy = new ServiceConnectionProxy();

            var connectionTask = proxy.WaitForServerConnectionAsync(1);

            _ = proxy.StartAsync();

            await connectionTask.OrTimeout();

            // 2 client connects with different instanceIds
            await proxy.WriteMessageAsync(new OpenConnectionMessage(connectionId1, null, header1, null));

            connectionTask = proxy.WaitForConnectionAsync(connectionId1);
            await connectionTask.OrTimeout();

            await proxy.WriteMessageAsync(new OpenConnectionMessage(connectionId2, null, header2, null));

            connectionTask = proxy.WaitForConnectionAsync(connectionId2);
            await connectionTask.OrTimeout();

            // Server received instance offline ping on instanceId1 and trigger cleanup related client1
            await proxy.WriteMessageAsync(new PingMessage()
            {
                Messages = new[] { "offline", instanceId1 }
            });

            // Validate client1 is closed and client2 is still connected
            var disconnectTask = proxy.WaitForConnectionCloseAsync(connectionId1);
            await disconnectTask.OrTimeout();

            Assert.Single(proxy.ClientConnections);
            Assert.Equal(connectionId2, proxy.ClientConnections.FirstOrDefault().Key);
        }
Пример #2
0
        public async Task ServiceConnectionStartsConnection()
        {
            var connectionId1 = Guid.NewGuid().ToString("N");
            var connectionId2 = Guid.NewGuid().ToString("N");

            var proxy = new ServiceConnectionProxy();

            var serverTask = proxy.WaitForServerConnectionAsync(1);

            _ = proxy.StartAsync();
            await serverTask.OrTimeout();

            Assert.Empty(proxy.ClientConnectionManager.ClientConnections);

            // Wait for the connection to appear, we need to do this before
            // sending the message to avoid races
            var connection1Task = proxy.WaitForConnectionAsync(connectionId1);

            // Create a new client connection
            await proxy.WriteMessageAsync(new OpenConnectionMessage(connectionId1, null));

            var connection1 = await connection1Task.OrTimeout();

            Assert.Single(proxy.ClientConnectionManager.ClientConnections);

            var httpContext1 = connection1.GetHttpContext();

            Assert.NotNull(httpContext1);
            Assert.Empty(httpContext1.Request.Headers);
            Assert.Empty(httpContext1.Request.Query);
            Assert.Equal(string.Empty, httpContext1.Request.Path);

            // Wait for the connection to appear
            var connectionTask2 = proxy.WaitForConnectionAsync(connectionId2);

            // Create another client connection
            const string headerKey1   = "custom-header-1";
            const string headerValue1 = "custom-value-1";
            const string headerKey2   = "custom-header-2";
            var          headerValue2 = new[] { "custom-value-2a", "custom-value-2b" };
            const string headerKey3   = "custom-header-3";
            var          headerValue3 = new[] { "custom-value-3a", "custom-value-3b", "custom-value-3c" };
            const string path         = "/this/is/user/path";

            await proxy.WriteMessageAsync(new OpenConnectionMessage(connectionId2, null,
                                                                    new Dictionary <string, StringValues>
            {
                { headerKey1, headerValue1 },
                { headerKey2, headerValue2 },
                { headerKey3, headerValue3 }
            },
                                                                    $"?customQuery1=customValue1&customQuery2=customValue2&{Constants.QueryParameter.OriginalPath}={WebUtility.UrlEncode(path)}"));

            var connection2 = await connectionTask2.OrTimeout();

            Assert.Equal(2, proxy.ClientConnectionManager.ClientConnections.Count);

            var httpContext2 = connection2.GetHttpContext();

            Assert.NotNull(httpContext2);
            Assert.Equal(3, httpContext2.Request.Headers.Count);
            Assert.Equal(headerValue1, httpContext2.Request.Headers[headerKey1]);
            Assert.Equal(headerValue2, httpContext2.Request.Headers[headerKey2]);
            Assert.Equal(headerValue3, httpContext2.Request.Headers[headerKey3]);
            Assert.Equal(3, httpContext2.Request.Query.Count);
            Assert.Equal("customValue1", httpContext2.Request.Query["customQuery1"]);
            Assert.Equal("customValue2", httpContext2.Request.Query["customQuery2"]);
            Assert.Equal(path, httpContext2.Request.Query[Constants.QueryParameter.OriginalPath]);
            Assert.Equal(path, httpContext2.Request.Path);

            // Send a message to client 1
            await proxy.WriteMessageAsync(new ConnectionDataMessage(connectionId1, Encoding.ASCII.GetBytes("Hello")));

            var item = await connection1.Transport.Input.ReadSingleAsync().OrTimeout();

            Assert.Equal("Hello", Encoding.ASCII.GetString(item));

            var connection1CloseTask = proxy.WaitForConnectionCloseAsync(connectionId1);

            // Close client 1
            await proxy.WriteMessageAsync(new CloseConnectionMessage(connectionId1, null));

            await connection1CloseTask.OrTimeout();

            Assert.Single(proxy.ClientConnectionManager.ClientConnections);

            // Close client 2
            var connection2CloseTask = proxy.WaitForConnectionCloseAsync(connectionId2);

            await proxy.WriteMessageAsync(new CloseConnectionMessage(connectionId2, null));

            await connection2CloseTask.OrTimeout();

            Assert.Empty(proxy.ClientConnectionManager.ClientConnections);

            proxy.Stop();
        }