internal IObservable <(HandshakeStateKind handshakeState, WebsocketClientLiteException?ex)> Handshake( Uri uri, WebsocketSenderHandler sender, TimeSpan timeout, CancellationToken ct, string?origin = null, IDictionary <string, string>?headers = null, IEnumerable <string>?subprotocols = null) { return(Observable.Create <(HandshakeStateKind handshakeState, WebsocketClientLiteException?ex)>(async obs => { using var parserDelegate = new HandshakeParserDelegate(obs); using var parserHandler = new HttpCombinedParser(parserDelegate); var handshakeParser = new HandshakeParser( parserHandler, parserDelegate, _connectionStatusAction); await SendHandshake(uri, sender, ct, origin, headers); await WaitForHandshake(handshakeParser); obs.OnCompleted(); }) .Timeout(timeout) .Catch < (HandshakeStateKind handshakeState, WebsocketClientLiteException?ex), TimeoutException>( tx => Observable.Return( (HandshakeStateKind.HandshakeTimedOut, new WebsocketClientLiteException("Handshake times out.", tx) ?? null) ) )); async Task WaitForHandshake(HandshakeParser handshakeParser) { bool isHandshakeDone; do { isHandshakeDone = await _tcpConnectionService .BytesObservable() .Select(b => handshakeParser.Parse(b, subprotocols)); } while (!isHandshakeDone); } }
internal WebsocketParserHandler( IObserver <ConnectionStatus> observerConnectionStatus, bool subprotocolAccepted, bool excludeZeroApplicationDataInPong) { _handshakeParser = new HandshakeParser(); var dataReceiveSubject = new BehaviorSubject <DataReceiveState>(DataReceiveState.Start); _textDataParser = new TextDataParser(); _observerConnectionStatus = observerConnectionStatus; _observerDataReceiveMode = dataReceiveSubject.AsObserver(); SubprotocolAccepted = subprotocolAccepted; ExcludeZeroApplicationDataInPong = excludeZeroApplicationDataInPong; DataReceiveStateObservable = dataReceiveSubject.AsObservable(); }