Пример #1
0
        internal IObservable <string> CreateWebsocketListenerObservable(
            Stream tcpStream,
            IEnumerable <string> subProtocols = null)
        {
            ParserDelegate = new HttpParserDelegate();
            var parserHandler = new HttpCombinedParser(ParserDelegate);

            _textDataParser.Reinitialize();

            _tcpStream = tcpStream;

            _observerDataReceiveMode.OnNext(DataReceiveState.IsListeningForHandShake);

            _dataReceiveState = DataReceiveState.IsListeningForHandShake;

            var listenerObservable = Observable.Create <string>(
                obs =>
            {
                var disposableReceiveState = DataReceiveStateObservable.Subscribe(s =>
                {
                    _dataReceiveState = s;
                },
                                                                                  obs.OnError,
                                                                                  () =>
                {
                    Debug.WriteLine("DataReceiveObservable completed");
                });

                var disposableStreamListener =
                    Observable.While(
                        () => _dataReceiveState == DataReceiveState.IsListeningForHandShake ||
                        _dataReceiveState == DataReceiveState.IsListening,
                        Observable.FromAsync(() => ReadOneByteAtTheTimeAsync(tcpStream)))
                    .Select(b => Observable.FromAsync(() => ParseWebSocketAsync(b, ParserDelegate, parserHandler, subProtocols, obs)))
                    .Concat()

                    .Subscribe(
                        _ =>
                {
                    if (_textDataParser.IsCloseReceived)
                    {
                        _observerDataReceiveMode.OnNext(DataReceiveState.Exiting);
                        _observerDataReceiveMode.OnCompleted();
                    }
                },
                        obs.OnError,
                        obs.OnCompleted);

                return(new CompositeDisposable(disposableReceiveState, disposableStreamListener));
            });

            return(listenerObservable);
        }
Пример #2
0
        internal IObservable <string> CreateObservableListener(
            CancellationTokenSource innerCancellationTokenSource,
            ITcpSocketClient tcpSocketClient,
            IEnumerable <string> subProtocols = null)
        {
            var parserDelegate = new HttpParserDelegate();
            var parserHandler  = new HttpCombinedParser(parserDelegate);

            TextDataParser.Reinitialize();

            _innerCancellationTokenSource = innerCancellationTokenSource;

            _tcpSocketClient = tcpSocketClient;

            DataReceiveMode = DataReceiveMode.IsListeningForHandShake;
            IsConnected     = false;
            _isHandshaking  = true;

            WatchHandshakeForTimeout(parserDelegate, _innerCancellationTokenSource);

            var observable = Observable.Create <string>(
                obs =>
            {
                var disp = _tcpSocketClient.ReadStream.ReadOneByteAtTheTimeObservable(innerCancellationTokenSource, isConnectionOpen: IsConnected || _isHandshaking)
                           .Subscribe(
                    b =>
                {
                    if (TextDataParser.IsCloseRecieved)
                    {
                        return;
                    }

                    if (_hasHandshakeTimedout)
                    {
                        _subjectConnectionStatus.OnNext(ConnectionStatus.Aborted);
                        throw new WebsocketClientLiteException("Connection request to server timed out");
                    }

                    switch (DataReceiveMode)
                    {
                    case DataReceiveMode.IsListeningForHandShake:

                        _handshakeParser.Parse(b, parserDelegate, parserHandler);

                        HandshakeController(parserDelegate, subProtocols);
                        break;

                    case DataReceiveMode.IsListeningForTextData:

                        TextDataParser.Parse(_tcpSocketClient, b[0], ExcludeZeroApplicationDataInPong);

                        if (TextDataParser.IsCloseRecieved)
                        {
                            StopReceivingData();
                        }

                        if (TextDataParser.HasNewMessage)
                        {
                            obs.OnNext(TextDataParser.NewMessage);
                        }
                        break;
                    }
                },
                    ex =>
                {
                    StopReceivingData();
                    throw ex;
                },
                    () =>
                {
                    // ReSharper disable once ConvertClosureToMethodGroup
                    StopReceivingData();
                }
                    );

                HasReceivedCloseFromServer = false;

                return(disp);
            });

            return(observable);
        }