Ejemplo n.º 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);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TcpConnection"/> class.
        /// </summary>
        /// <param name="client">The associated socket.</param>
        /// <param name="littleEndianByteOrder">The expected endianness of integral value types.</param>
        public TcpConnection(Socket client, bool littleEndianByteOrder = true)
        {
            Assert.ParamIsNotNull(client);

            mClient = client;
            mNetworkStream = new NetworkStream(client);
            mReader = new BinaryReader(mNetworkStream);
            mWriter = new BinaryWriter(mNetworkStream);
            mLittleEndianByteOrder = littleEndianByteOrder;

            mReceiveState = DataReceiveState.MessageFraming;
            mPartiallyReceivedData = new byte[ReceivedDataBufferSize];
            mCompletelyReceivedData = new List<byte>();
            mMessageLengthData = new byte[4];
            mBytesToProcessRemaining = 0;
        }
Ejemplo n.º 3
0
 public EODataChunk()
     : base(BUFFER_SIZE)
 {
     State     = DataReceiveState.ReadLen1;
     RawLength = new byte[2];
 }
Ejemplo n.º 4
0
 public EODataChunk()
     : base(BUFFER_SIZE)
 {
     State = DataReceiveState.ReadLen1;
     RawLength = new byte[2];
 }
        /// <summary>
        /// The callback paired with Socket.BeginReceive().
        /// </summary>
        /// <param name="asyncResult"></param>
        private void DataReceivedCallback(IAsyncResult asyncResult)
        {
            if (mIsClosed)
            {
                return;
            }

            try
            {
                int bytesReceived = mClient.EndReceive(asyncResult);
                if (bytesReceived > 0)
                {
                    mBytesToProcessRemaining = bytesReceived;
                    mCompletelyReceivedData.AddRange(new SubArray<byte>(mPartiallyReceivedData, 0, bytesReceived));

                    while (mBytesToProcessRemaining > 0)
                    {
                        switch (mReceiveState)
                        {
                            case TcpConnection.DataReceiveState.MessageFraming:
                            {
                                // Read message length
                                if (mCompletelyReceivedData.Count >= 4)
                                {
                                    mCompletelyReceivedData.CopyTo(0, mMessageLengthData, 0, 4);
                                    if (BitConverter.IsLittleEndian != mLittleEndianByteOrder)
                                    {
                                        mMessageLengthData = Utility.SwapEndian(mMessageLengthData);
                                    }

                                    mMessageLength = BitConverter.ToInt32(mMessageLengthData, 0);
                                    Assert.IsTrue(mMessageLength > 0);

                                    mReceiveState = TcpConnection.DataReceiveState.Message;
                                    mCompletelyReceivedData.RemoveRange(0, 4);
                                    mBytesToProcessRemaining -= 4;
                                }

                                break;
                            }

                            case DataReceiveState.Message:
                            {
                                if (mCompletelyReceivedData.Count >= mMessageLength)
                                {
                                    byte[] message = new byte[mMessageLength];
                                    mCompletelyReceivedData.CopyTo(0, message, 0, mMessageLength);
                                    OnDataReceived(new TcpDataReceivedEventArgs(this, message));

                                    mReceiveState = TcpConnection.DataReceiveState.MessageFraming;
                                    mCompletelyReceivedData.RemoveRange(0, mMessageLength);
                                }

                                mBytesToProcessRemaining = 0;
                                break;
                            }
                        }
                    }

                    InitDataReceivedCallback();
                }
                else
                {
                    // bytesReceived == 0 when the socket gets shutdown; therefore, remove the connection.
                    mCompletelyReceivedData.Clear();
                    Close();
                    return;
                }
            }
            catch
            {
                Close();
            }
        }