Exemplo n.º 1
0
        public async Task SubProtocolSelectorIsUsedToSelectSubProtocol()
        {
            const string ExpectedSubProtocol  = "expected";
            var          providedSubProtocols = new[] { "provided1", "provided2" };

            using (StartVerifiableLog(out var loggerFactory, LogLevel.Debug))
            {
                var pair       = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
                var connection = new HttpConnectionContext("foo", pair.Transport, pair.Application);

                using (var feature = new TestWebSocketConnectionFeature())
                {
                    var options = new WebSocketOptions
                    {
                        // We want to verify behavior without timeout affecting it
                        CloseTimeout        = TimeSpan.FromSeconds(20),
                        SubProtocolSelector = protocols => {
                            Assert.Equal(providedSubProtocols, protocols.ToArray());
                            return(ExpectedSubProtocol);
                        },
                    };

                    var connectionContext = new HttpConnectionContext(string.Empty, null, null);
                    var ws = new WebSocketsTransport(options, connection.Application, connectionContext, loggerFactory);

                    // Create an HttpContext
                    var context = new DefaultHttpContext();
                    context.Request.Headers.Add(HeaderNames.WebSocketSubProtocols, providedSubProtocols.ToArray());
                    context.Features.Set <IHttpWebSocketFeature>(feature);
                    var transport = ws.ProcessRequestAsync(context, CancellationToken.None);

                    await feature.Accepted.OrThrowIfOtherFails(transport);

                    // Assert the feature got the right subprotocol
                    Assert.Equal(ExpectedSubProtocol, feature.SubProtocol);

                    // Run the client socket
                    var client = feature.Client.ExecuteAndCaptureFramesAsync();

                    await feature.Client.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None).OrTimeout();

                    // close the client to server channel
                    connection.Transport.Output.Complete();

                    _ = await client.OrTimeout();

                    await transport.OrTimeout();
                }
            }
        }