public TcpServerQuery(TcpServerQbservableProvider <TSource> provider, Expression expression, object argument)
     : base(provider, expression)
 {
     this.argument = argument;
 }
Пример #2
0
        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)));
        }