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; } } }