private async Task <WebSocketClientTermination> AcceptAsync( HttpListenerWebSocketContext context, CapturedId capturedId, CapturedShutdownReason capturedShutdownReason, QbservableServiceOptions options, Func <IQbservableProtocol, IParameterizedQbservableProvider> providerFactory, CancellationToken cancel) { Contract.Requires(context != null); Contract.Requires(capturedId != null); Contract.Requires(capturedShutdownReason != null); Contract.Requires(options != null); Contract.Requires(providerFactory != null); ReceivingConnection(idOverride: capturedId.Value); prepareSocket(context.WebSocket); var watch = Stopwatch.StartNew(); var exceptions = new List <ExceptionDispatchInfo>(); var shutdownReason = QbservableProtocolShutdownReason.None; try { using (var stream = new WebSocketStream(context.WebSocket)) using (var protocol = await NegotiateServerAsync(capturedId.Value, stream, formatterFactory(), options, cancel).ConfigureAwait(false)) { capturedId.Value = protocol.ClientId; var provider = providerFactory(protocol); ReceivedConnection(idOverride: capturedId.Value); try { await protocol.ExecuteServerAsync(provider).ConfigureAwait(false); } catch (OperationCanceledException) { } catch (Exception ex) { exceptions.Add(ExceptionDispatchInfo.Capture(ex)); } finally { shutdownReason = protocol.ShutdownReason; } var protocolExceptions = protocol.Exceptions; if (protocolExceptions != null) { foreach (var exception in protocolExceptions) { exceptions.Add(exception); } } } } catch (OperationCanceledException) { shutdownReason = QbservableProtocolShutdownReason.ProtocolNegotiationCanceled; } catch (Exception ex) { shutdownReason = QbservableProtocolShutdownReason.ProtocolNegotiationError; exceptions.Add(ExceptionDispatchInfo.Capture(ex)); } finally { capturedShutdownReason.Value = shutdownReason; } return(new WebSocketClientTermination(Uri, context.Origin, watch.Elapsed, shutdownReason, exceptions)); }
private IObservable <TResult> GetObservable <TResult>(Stream stream, Func <IQbservableProtocol, Expression> prepareExpression, CapturedShutdownReason capturedShutdownReason, CancellationToken cancel) { Contract.Requires(stream != null); Contract.Requires(prepareExpression != null); Contract.Ensures(Contract.Result <IObservable <TResult> >() != null); return(from protocol in NegotiateClientAsync(stream, formatterFactory(), cancel).ToObservable() from result in protocol .ExecuteClient <TResult>(prepareExpression(protocol), Argument) .Finally(() => { capturedShutdownReason.Value = protocol.ShutdownReason; protocol.Dispose(); }) select result); }