public bool TryReceive(TimeSpan timeout, out RequestContext requestContext)
        {
            Message message;

            if (this.channel.State == CommunicationState.Faulted)
            {
                this.AbortRequests();
                requestContext = null;
                return(true);
            }
            if (this.channel.TryReceive(timeout, out message))
            {
                if (message != null)
                {
                    requestContext = new DuplexRequestContext(this.channel, message, this);
                }
                else
                {
                    this.AbortRequests();
                    requestContext = null;
                }
                return(true);
            }
            requestContext = null;
            return(false);
        }
        public bool EndTryReceive(IAsyncResult result, out RequestContext requestContext)
        {
            Message message;

            if (result is ChannelFaultedAsyncResult)
            {
                this.AbortRequests();
                requestContext = null;
                return(true);
            }
            if (this.channel.EndTryReceive(result, out message))
            {
                if (message != null)
                {
                    requestContext = new DuplexRequestContext(this.channel, message, this);
                }
                else
                {
                    this.AbortRequests();
                    requestContext = null;
                }
                return(true);
            }
            requestContext = null;
            return(false);
        }
        public async Task OnConnectedAsync(FramingConnection connection)
        {
            var be  = connection.ServiceDispatcher.Binding.CreateBindingElements();
            var tbe = be.Find <TransportBindingElement>();
            ITransportFactorySettings settings = new NetFramingTransportSettings
            {
                CloseTimeout           = connection.ServiceDispatcher.Binding.CloseTimeout,
                OpenTimeout            = connection.ServiceDispatcher.Binding.OpenTimeout,
                ReceiveTimeout         = connection.ServiceDispatcher.Binding.ReceiveTimeout,
                SendTimeout            = connection.ServiceDispatcher.Binding.SendTimeout,
                ManualAddressing       = tbe.ManualAddressing,
                BufferManager          = connection.BufferManager,
                MaxReceivedMessageSize = tbe.MaxReceivedMessageSize,
                MessageEncoderFactory  = connection.MessageEncoderFactory
            };

            var channel = new ServerFramingDuplexSessionChannel(connection, settings, false, _servicesScopeFactory.CreateScope().ServiceProvider);
            await channel.OpenAsync();

            using (_appLifetime.ApplicationStopping.Register(() =>
            {
                _ = channel.CloseAsync();
            }))
            {
                var channelDispatcher = connection.ServiceDispatcher.CreateServiceChannelDispatcher(channel);
                while (true)
                {
                    Message message = await ReceiveMessageAsync(connection);

                    if (message == null)
                    {
                        await channel.CloseAsync();

                        return; // No more messages
                    }
                    var requestContext = new DuplexRequestContext(channel, message, connection.ServiceDispatcher.Binding);
                    // TODO: Create a correctly timing out ct
                    // We don't await DispatchAsync because in a concurrent service we want to read the next request before the previous
                    // request has finished.
                    _ = channelDispatcher.DispatchAsync(requestContext, CancellationToken.None);
                    // TODO: Now there's a channel dispatcher, have that handle negotiateing a Task which completes when it's time to get the next request
                    await requestContext.OperationDispatching;
                }
            }
        }