Exemple #1
0
        public TestClient(bool synchronousCallbacks = false, IHubProtocol protocol = null, IInvocationBinder invocationBinder = null, bool addClaimId = false)
        {
            var options = new ChannelOptimizations {
                AllowSynchronousContinuations = synchronousCallbacks
            };
            var transportToApplication = Channel.CreateUnbounded <byte[]>(options);
            var applicationToTransport = Channel.CreateUnbounded <byte[]>(options);

            Application = ChannelConnection.Create <byte[]>(input: applicationToTransport, output: transportToApplication);
            _transport  = ChannelConnection.Create <byte[]>(input: transportToApplication, output: applicationToTransport);

            Connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), _transport, Application);

            var claimValue = Interlocked.Increment(ref _id).ToString();
            var claims     = new List <Claim> {
                new Claim(ClaimTypes.Name, claimValue)
            };

            if (addClaimId)
            {
                claims.Add(new Claim(ClaimTypes.NameIdentifier, claimValue));
            }

            Connection.User = new ClaimsPrincipal(new ClaimsIdentity(claims));
            Connection.Metadata["ConnectedTask"] = new TaskCompletionSource <bool>();

            protocol = protocol ?? new JsonHubProtocol();
            _protocolReaderWriter = new HubProtocolReaderWriter(protocol, new PassThroughEncoder());
            _invocationBinder     = invocationBinder ?? new DefaultInvocationBinder();

            _cts = new CancellationTokenSource();

            using (var memoryStream = new MemoryStream())
            {
                NegotiationProtocol.WriteMessage(new NegotiationMessage(protocol.Name), memoryStream);
                Application.Out.TryWrite(memoryStream.ToArray());
            }
        }
Exemple #2
0
        public async Task ServerGracefullyClosesWhenApplicationEndsThenClientSendsCloseFrame()
        {
            var transportToApplication = Channel.CreateUnbounded <byte[]>();
            var applicationToTransport = Channel.CreateUnbounded <byte[]>();

            using (var transportSide = ChannelConnection.Create <byte[]>(applicationToTransport, transportToApplication))
                using (var applicationSide = ChannelConnection.Create <byte[]>(transportToApplication, applicationToTransport))
                    using (var feature = new TestWebSocketConnectionFeature())
                    {
                        var options = new WebSocketOptions
                        {
                            // We want to verify behavior without timeout affecting it
                            CloseTimeout = TimeSpan.FromSeconds(20)
                        };

                        var connectionContext = new DefaultConnectionContext(string.Empty, null, null);
                        var ws = new WebSocketsTransport(options, transportSide, connectionContext, loggerFactory: new LoggerFactory());

                        var serverSocket = await feature.AcceptAsync();

                        // Give the server socket to the transport and run it
                        var transport = ws.ProcessSocketAsync(serverSocket);

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

                        // close the client to server channel
                        applicationToTransport.Out.TryComplete();

                        _ = await client.OrTimeout();

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

                        await transport.OrTimeout();

                        Assert.Equal(WebSocketCloseStatus.NormalClosure, serverSocket.CloseStatus);
                    }
        }
Exemple #3
0
        private async Task StartTransport(Uri connectUrl)
        {
            var applicationToTransport = Channel.CreateUnbounded <SendMessage>();
            var transportToApplication = Channel.CreateUnbounded <byte[]>();
            var applicationSide        = ChannelConnection.Create(applicationToTransport, transportToApplication);

            _transportChannel = ChannelConnection.Create(transportToApplication, applicationToTransport);

            // Start the transport, giving it one end of the pipeline
            try
            {
                await _transport.StartAsync(connectUrl, applicationSide, requestedTransferMode : GetTransferMode(), connectionId : _connectionId);

                // actual transfer mode can differ from the one that was requested so set it on the feature
                Debug.Assert(_transport.Mode.HasValue, "transfer mode not set after transport started");
                SetTransferMode(_transport.Mode.Value);
            }
            catch (Exception ex)
            {
                _logger.ErrorStartingTransport(_connectionId, _transport.GetType().Name, ex);
                throw;
            }
        }
Exemple #4
0
        public async Task TransportFailsOnTimeoutWithErrorWhenApplicationFailsAndClientDoesNotSendCloseFrame()
        {
            using (StartLog(out var loggerFactory))
            {
                var transportToApplication = Channel.CreateUnbounded <byte[]>();
                var applicationToTransport = Channel.CreateUnbounded <byte[]>();

                using (var transportSide = ChannelConnection.Create <byte[]>(applicationToTransport, transportToApplication))
                    using (var applicationSide = ChannelConnection.Create <byte[]>(transportToApplication, applicationToTransport))
                        using (var feature = new TestWebSocketConnectionFeature())
                        {
                            var options = new WebSocketOptions
                            {
                                CloseTimeout = TimeSpan.FromSeconds(1)
                            };

                            var connectionContext = new DefaultConnectionContext(string.Empty, null, null);
                            var ws = new WebSocketsTransport(options, transportSide, connectionContext, loggerFactory);

                            var serverSocket = await feature.AcceptAsync();

                            // Give the server socket to the transport and run it
                            var transport = ws.ProcessSocketAsync(serverSocket);

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

                            // fail the client to server channel
                            applicationToTransport.Writer.TryComplete(new Exception());

                            await Assert.ThrowsAsync <Exception>(() => transport).OrTimeout();

                            Assert.Equal(WebSocketState.Aborted, serverSocket.State);
                        }
            }
        }
Exemple #5
0
        public async Task TransportClosesOnCloseTimeoutIfClientDoesNotSendCloseFrame()
        {
            using (StartLog(out var loggerFactory))
            {
                var transportToApplication = Channel.CreateUnbounded <byte[]>();
                var applicationToTransport = Channel.CreateUnbounded <byte[]>();

                using (var transportSide = ChannelConnection.Create <byte[]>(applicationToTransport, transportToApplication))
                    using (var applicationSide = ChannelConnection.Create <byte[]>(transportToApplication, applicationToTransport))
                        using (var feature = new TestWebSocketConnectionFeature())
                        {
                            var options = new WebSocketOptions()
                            {
                                CloseTimeout = TimeSpan.FromSeconds(1)
                            };

                            var connectionContext = new DefaultConnectionContext(string.Empty, null, null);
                            var ws = new WebSocketsTransport(options, transportSide, connectionContext, loggerFactory);

                            var serverSocket = await feature.AcceptAsync();

                            // Give the server socket to the transport and run it
                            var transport = ws.ProcessSocketAsync(serverSocket);

                            // End the app
                            applicationSide.Dispose();

                            await transport.OrTimeout(TimeSpan.FromSeconds(10));

                            // Now we're closed
                            Assert.Equal(WebSocketState.Aborted, serverSocket.State);

                            serverSocket.Dispose();
                        }
            }
        }