public TcpServerQuery(TcpServerQbservableProvider <TSource> provider, Expression expression, object argument) : base(provider, expression) { this.argument = argument; }
private static IObservable <TcpClientTermination> CreateService <TSource, TResult>( IPEndPoint endPoint, Func <IRemotingFormatter> formatterFactory, QbservableServiceOptions options, Func <IObservable <TSource>, IQbservable <TResult> > service) { return(ObservableTcpListener .Start(endPoint, maxConcurrent: 1) // maxConcurrent must be 1 to ensure thread-safety. See the Start method's remarks for details. .SelectMany(client => Observable .StartAsync(async cancel => { var watch = Stopwatch.StartNew(); // disable Nagle algorithm so that observed events are sent as soon as they happen client.NoDelay = true; var localEndPoint = client.Client.LocalEndPoint; var remoteEndPoint = client.Client.RemoteEndPoint; var exceptions = new List <ExceptionDispatchInfo>(); var shutDownReason = QbservableProtocolShutDownReason.None; try { using (var stream = client.GetStream()) using (var protocol = await QbservableProtocol.NegotiateServerAsync(stream, formatterFactory(), options, cancel).ConfigureAwait(false)) { var provider = new TcpServerQbservableProvider <TResult>( protocol, options, argument => { if (argument == null && typeof(TSource).IsValueType) { return service(Observable.Return(default(TSource))); } else { return service(Observable.Return((TSource)argument)); } }); try { await protocol.ExecuteServerAsync(provider).ConfigureAwait(false); } catch (OperationCanceledException) { } catch (Exception ex) { exceptions.Add(ExceptionDispatchInfo.Capture(ex)); } var protocolExceptions = protocol.Exceptions; if (protocolExceptions != null) { foreach (var exception in protocolExceptions) { exceptions.Add(exception); } } shutDownReason = protocol.ShutDownReason; } } catch (OperationCanceledException) { shutDownReason = QbservableProtocolShutDownReason.ProtocolNegotiationCancelled; } catch (Exception ex) { shutDownReason = QbservableProtocolShutDownReason.ProtocolNegotiationError; exceptions.Add(ExceptionDispatchInfo.Capture(ex)); } return new TcpClientTermination(localEndPoint, remoteEndPoint, watch.Elapsed, shutDownReason, exceptions); }) .Finally(client.Close))); }