Example #1
0
        private void ReceiveBuffer(int receiveCount)
        {
            // TCP guarantees delivery of all packets in the correct order.
            // But there is no guarantee that one write operation on the sender-side will result in
            // one read event on the receiving side. One call of write(message) by the sender
            // can result in multiple messageReceived(session, message) events on the receiver;
            // and multiple calls of write(message) can lead to a single messageReceived event.
            // In a stream-based transport such as TCP/IP, received data is stored into a socket receive buffer.
            // Unfortunately, the buffer of a stream-based transport is not a queue of packets but a queue of bytes.
            // It means, even if you sent two messages as two independent packets,
            // an operating system will not treat them as two messages but as just a bunch of bytes.
            // Therefore, there is no guarantee that what you read is exactly what your remote peer wrote.
            // There are three common techniques for splitting the stream of bytes into messages:
            //   1. use fixed length messages
            //   2. use a fixed length header that indicates the length of the body
            //   3. using a delimiter; for example many text-based protocols append
            //      a newline (or CR LF pair) after every message.
            int frameLength;

            byte[] payload;
            int    payloadOffset;
            int    payloadCount;
            int    consumedLength = 0;

            SegmentBufferDeflector.ReplaceBuffer(_bufferManager, ref _receiveBuffer, ref _receiveBufferOffset, receiveCount);

            while (true)
            {
                frameLength   = 0;
                payload       = null;
                payloadOffset = 0;
                payloadCount  = 0;

                if (_configuration.FrameBuilder.Decoder.TryDecodeFrame(
                        _receiveBuffer.Array,
                        _receiveBuffer.Offset + consumedLength,
                        _receiveBufferOffset - consumedLength,
                        out frameLength, out payload, out payloadOffset, out payloadCount))
                {
                    try
                    {
                        _server.RaiseClientDataReceived(this, payload, payloadOffset, payloadCount);
                    }
                    catch (Exception ex)
                    {
                        HandleUserSideError(ex);
                    }
                    finally
                    {
                        consumedLength += frameLength;
                    }
                }
                else
                {
                    break;
                }
            }

            SegmentBufferDeflector.ShiftBuffer(_bufferManager, consumedLength, ref _receiveBuffer, ref _receiveBufferOffset);
        }
        private async Task Process()
        {
            try
            {
                int    frameLength;
                byte[] payload;
                int    payloadOffset;
                int    payloadCount;
                int    consumedLength = 0;

                while (State == TcpSocketConnectionState.Connected)
                {
                    int receiveCount = await _stream.ReadAsync(
                        _receiveBuffer.Array,
                        _receiveBuffer.Offset + _receiveBufferOffset,
                        _receiveBuffer.Count - _receiveBufferOffset);

                    if (receiveCount == 0)
                    {
                        break;
                    }

                    SegmentBufferDeflector.ReplaceBuffer(_bufferManager, ref _receiveBuffer, ref _receiveBufferOffset, receiveCount);
                    consumedLength = 0;

                    while (true)
                    {
                        frameLength   = 0;
                        payload       = null;
                        payloadOffset = 0;
                        payloadCount  = 0;

                        if (_configuration.FrameBuilder.Decoder.TryDecodeFrame(
                                _receiveBuffer.Array,
                                _receiveBuffer.Offset + consumedLength,
                                _receiveBufferOffset - consumedLength,
                                out frameLength, out payload, out payloadOffset, out payloadCount))
                        {
                            try
                            {
                                await _dispatcher.OnSessionDataReceived(this, payload, payloadOffset, payloadCount);
                            }
                            catch (Exception ex) // catch all exceptions from out-side
                            {
                                await HandleUserSideError(ex);
                            }
                            finally
                            {
                                consumedLength += frameLength;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (_receiveBuffer != null && _receiveBuffer.Array != null)
                    {
                        SegmentBufferDeflector.ShiftBuffer(_bufferManager, consumedLength, ref _receiveBuffer, ref _receiveBufferOffset);
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                // looking forward to a graceful quit from the ReadAsync but the inside EndRead will raise the ObjectDisposedException,
                // so a gracefully close for the socket should be a Shutdown, but we cannot avoid the Close triggers this happen.
            }
            catch (Exception ex)
            {
                await HandleReceiveOperationException(ex);
            }
            finally
            {
                await Close(true); // read async buffer returned, remote notifies closed
            }
        }
Example #3
0
        private async Task Process()
        {
            try
            {
                int    frameLength;
                byte[] payload;
                int    payloadOffset;
                int    payloadCount;
                int    consumedLength = 0;

                var saea = _saeaPool.Take();
                saea.Saea.SetBuffer(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                while (State == TcpSocketConnectionState.Connected)
                {
                    saea.Saea.SetBuffer(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                    var socketError = await _socket.ReceiveAsync(saea);

                    if (socketError != SocketError.Success)
                    {
                        break;
                    }

                    var receiveCount = saea.Saea.BytesTransferred;
                    if (receiveCount == 0)
                    {
                        break;
                    }

                    SegmentBufferDeflector.ReplaceBuffer(_configuration.BufferManager, ref _receiveBuffer, ref _receiveBufferOffset, receiveCount);
                    consumedLength = 0;

                    while (true)
                    {
                        frameLength   = 0;
                        payload       = null;
                        payloadOffset = 0;
                        payloadCount  = 0;

                        if (_configuration.FrameBuilder.Decoder.TryDecodeFrame(_receiveBuffer.Array, _receiveBuffer.Offset + consumedLength, _receiveBufferOffset - consumedLength,
                                                                               out frameLength, out payload, out payloadOffset, out payloadCount))
                        {
                            try
                            {
                                await _dispatcher.OnServerDataReceived(this, payload, payloadOffset, payloadCount);
                            }
                            catch (Exception ex)
                            {
                                HandleUserSideError(ex);
                            }
                            finally
                            {
                                consumedLength += frameLength;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    try
                    {
                        SegmentBufferDeflector.ShiftBuffer(_configuration.BufferManager, consumedLength, ref _receiveBuffer, ref _receiveBufferOffset);
                    }
                    catch (ArgumentOutOfRangeException) { }
                }
            }
            catch (Exception ex) when(!ShouldThrow(ex))
            {
            }
            finally
            {
                await Close();
            }
        }
Example #4
0
        private async Task Process()
        {
            try
            {
                int    frameLength;
                byte[] payload;
                int    payloadOffset;
                int    payloadCount;
                int    consumedLength = 0;

                var saea = _saeaPool.Take();
                saea.Saea.SetBuffer(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                while (State == TcpSocketConnectionState.Connected)
                {
                    saea.Saea.SetBuffer(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                    var socketError = await _socket.ReceiveAsync(saea);

                    if (socketError != SocketError.Success)
                    {
                        break;
                    }

                    var receiveCount = saea.Saea.BytesTransferred;
                    if (receiveCount == 0)
                    {
                        break;
                    }

                    SegmentBufferDeflector.ReplaceBuffer(_configuration.BufferManager, ref _receiveBuffer, ref _receiveBufferOffset, receiveCount);
                    consumedLength = 0;

                    while (true)
                    {
                        frameLength   = 0;
                        payload       = null;
                        payloadOffset = 0;
                        payloadCount  = 0;

                        if (_configuration.FrameBuilder.Decoder.TryDecodeFrame(_receiveBuffer.Array, _receiveBuffer.Offset + consumedLength, _receiveBufferOffset - consumedLength,
                                                                               out frameLength, out payload, out payloadOffset, out payloadCount))
                        {
                            try
                            {
                                await _dispatcher.OnServerDataReceived(this, payload, payloadOffset, payloadCount);
                            }
                            catch (Exception ex) // catch all exceptions from out-side
                            {
                                await HandleUserSideError(ex);
                            }
                            finally
                            {
                                consumedLength += frameLength;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (_receiveBuffer != null && _receiveBuffer.Array != null)
                    {
                        SegmentBufferDeflector.ShiftBuffer(_configuration.BufferManager, consumedLength, ref _receiveBuffer, ref _receiveBufferOffset);
                    }
                }
            }
            catch (Exception ex)
            {
                await HandleReceiveOperationException(ex);
            }
            finally
            {
                await Close(true); // read async buffer returned, remote notifies closed
            }
        }
Example #5
0
        private async Task Process()
        {
            try
            {
                int    frameLength;
                byte[] payload;
                int    payloadOffset;
                int    payloadCount;
                int    consumedLength = 0;

                while (State == TcpSocketConnectionState.Connected)
                {
                    int receiveCount = await _stream.ReadAsync(_receiveBuffer.Array, _receiveBuffer.Offset + _receiveBufferOffset, _receiveBuffer.Count - _receiveBufferOffset);

                    if (receiveCount == 0)
                    {
                        break;
                    }

                    SegmentBufferDeflector.ReplaceBuffer(_bufferManager, ref _receiveBuffer, ref _receiveBufferOffset, receiveCount);
                    consumedLength = 0;

                    while (true)
                    {
                        frameLength   = 0;
                        payload       = null;
                        payloadOffset = 0;
                        payloadCount  = 0;

                        if (_configuration.FrameBuilder.Decoder.TryDecodeFrame(
                                _receiveBuffer.Array,
                                _receiveBuffer.Offset + consumedLength,
                                _receiveBufferOffset - consumedLength,
                                out frameLength, out payload, out payloadOffset, out payloadCount))
                        {
                            try
                            {
                                await _dispatcher.OnSessionDataReceived(this, payload, payloadOffset, payloadCount);
                            }
                            catch (Exception ex)
                            {
                                await HandleUserSideError(ex);
                            }
                            finally
                            {
                                consumedLength += frameLength;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    SegmentBufferDeflector.ShiftBuffer(_bufferManager, consumedLength, ref _receiveBuffer, ref _receiveBufferOffset);
                }
            }
            catch (Exception ex)
            {
                await HandleReceiveOperationException(ex);
            }
            finally
            {
                await Close();
            }
        }
        public async Task Start()
        {
            var webSocket = this.Context.WebSocket;
            ArraySegment <byte> receiveBuffer = _bufferManager.BorrowBuffer();
            ArraySegment <byte> sessionBuffer = _bufferManager.BorrowBuffer();
            int sessionBufferCount            = 0;

            _log.DebugFormat("Session started for [{0}] on [{1}] in module [{2}] with session count [{3}].",
                             this.RemoteEndPoint,
                             this.StartTime.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"),
                             this.Module.ModuleName,
                             this.Module.SessionCount);
            try
            {
                while (webSocket.State == WebSocketState.Open)
                {
                    this.CancellationToken.ThrowIfCancellationRequested();

                    var receiveResult = await webSocket.ReceiveAsync(receiveBuffer, this.CancellationToken);

                    switch (receiveResult.MessageType)
                    {
                    case WebSocketMessageType.Text:
                    {
                        if (receiveResult.EndOfMessage && sessionBufferCount == 0)
                        {
                            var message = new WebSocketTextMessage(this, this.Encoding.GetString(receiveBuffer.Array, receiveBuffer.Offset, receiveResult.Count));
                            await this.Module.ReceiveTextMessage(message);
                        }
                        else
                        {
                            SegmentBufferDeflector.AppendBuffer(_bufferManager, ref receiveBuffer, receiveResult.Count, ref sessionBuffer, ref sessionBufferCount);

                            if (receiveResult.EndOfMessage)
                            {
                                var message = new WebSocketTextMessage(this, this.Encoding.GetString(sessionBuffer.Array, sessionBuffer.Offset, sessionBufferCount));
                                await this.Module.ReceiveTextMessage(message);

                                sessionBufferCount = 0;
                            }
                        }
                    }
                    break;

                    case WebSocketMessageType.Binary:
                    {
                        if (receiveResult.EndOfMessage && sessionBufferCount == 0)
                        {
                            var message = new WebSocketBinaryMessage(this, receiveBuffer.Array, receiveBuffer.Offset, receiveResult.Count);
                            await this.Module.ReceiveBinaryMessage(message);
                        }
                        else
                        {
                            SegmentBufferDeflector.AppendBuffer(_bufferManager, ref receiveBuffer, receiveResult.Count, ref sessionBuffer, ref sessionBufferCount);

                            if (receiveResult.EndOfMessage)
                            {
                                var message = new WebSocketBinaryMessage(this, sessionBuffer.Array, sessionBuffer.Offset, sessionBufferCount);
                                await this.Module.ReceiveBinaryMessage(message);

                                sessionBufferCount = 0;
                            }
                        }
                    }
                    break;

                    case WebSocketMessageType.Close:
                    {
                        await Close(
                            receiveResult.CloseStatus.HasValue?receiveResult.CloseStatus.Value : WebSocketCloseStatus.NormalClosure,
                            receiveResult.CloseStatusDescription);
                    }
                    break;
                    }
                }
            }
            catch (WebSocketException) { }
            finally
            {
                _bufferManager.ReturnBuffer(receiveBuffer);
                _bufferManager.ReturnBuffer(sessionBuffer);

                _log.DebugFormat("Session closed for [{0}] on [{1}] in module [{2}] with session count [{3}].",
                                 this.RemoteEndPoint,
                                 DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"),
                                 this.Module.ModuleName,
                                 this.Module.SessionCount - 1);

                if (webSocket != null)
                {
                    webSocket.Dispose();
                }
            }
        }