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 scope   = _servicesScopeFactory.CreateScope();
            var channel = new ServerFramingDuplexSessionChannel(connection, settings, false, _servicesScopeFactory.CreateScope().ServiceProvider);
            await channel.OpenAsync();

            var decoder           = connection.ServerSessionDecoder;
            var serviceDispatcher = connection.ServiceDispatcher;

            while (true)
            {
                Message message = await ReceiveMessageAsync(connection);

                if (message == null)
                {
                    return; // No more messages
                }
                // TODO: Create a correctly timing out ct
                await serviceDispatcher.DispatchAsync(new DuplexRequestContext(channel, message, connection.ServiceDispatcher.Binding), channel, CancellationToken.None);
            }
        }
        public async Task OnConnectedAsync(FramingConnection connection)
        {
            if (!_transportSettingsCache.TryGetValue(connection.ServiceDispatcher, out ITransportFactorySettings settings))
            {
                BindingElementCollection be  = connection.ServiceDispatcher.Binding.CreateBindingElements();
                TransportBindingElement  tbe = be.Find <TransportBindingElement>();
                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);

            channel.ChannelDispatcher = await connection.ServiceDispatcher.CreateServiceChannelDispatcherAsync(channel);

            await channel.StartReceivingAsync();
        }
        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;
                }
            }
        }