Microsoft.AspNetCore.WebSockets.Protocol.CommonWebSocket.ReceiveAsync C# (CSharp) Method

ReceiveAsync() public method

public ReceiveAsync ( ArraySegment buffer, CancellationToken cancellationToken ) : Task
buffer ArraySegment
cancellationToken System.Threading.CancellationToken
return Task
        public async override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();
            ThrowIfInputClosed();
            ValidateSegment(buffer);
            // TODO: InvalidOperationException if any receives are currently in progress.

            // No active frame. Loop because we may be discarding ping/pong frames.
            while (_frameInProgress == null)
            {
                await ReadNextFrameAsync(cancellationToken);
            }

            int opCode = _frameInProgress.OpCode;

            if (opCode == Constants.OpCodes.CloseFrame)
            {
                return await ProcessCloseFrameAsync(cancellationToken);
            }

            // Handle fragmentation, remember the first frame type
            if (opCode == Constants.OpCodes.ContinuationFrame)
            {
                if (!_firstDataOpCode.HasValue)
                {
                    await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid continuation frame", cancellationToken);
                }
                opCode = _firstDataOpCode.Value;
            }
            else
            {
                _firstDataOpCode = opCode;
            }

            // Make sure there's at least some data in the buffer
            int bytesToBuffer = (int)Math.Min((long)_receiveBuffer.Length, _frameBytesRemaining);
            await EnsureDataAvailableOrReadAsync(bytesToBuffer, cancellationToken);

            // Copy buffered data to the users buffer
            int bytesToRead = (int)Math.Min((long)buffer.Count, _frameBytesRemaining);
            int bytesToCopy = Math.Min(bytesToRead, _receiveBufferBytes);
            Array.Copy(_receiveBuffer, _receiveBufferOffset, buffer.Array, buffer.Offset, bytesToCopy);

            if (_unmaskInput)
            {
                // _frameInProgress.Masked == _unmaskInput already verified
                Utilities.MaskInPlace(_frameInProgress.MaskKey, ref _dataUnmaskOffset, new ArraySegment<byte>(buffer.Array, buffer.Offset, bytesToCopy));
            }

            WebSocketReceiveResult result;
            WebSocketMessageType messageType = Utilities.GetMessageType(opCode);

            if (messageType == WebSocketMessageType.Text
                && !Utilities.TryValidateUtf8(new ArraySegment<byte>(buffer.Array, buffer.Offset, bytesToCopy), _frameInProgress.Fin, _incomingUtf8MessageState))
            {
                await SendErrorAbortAndThrow(WebSocketCloseStatus.InvalidPayloadData, "Invalid UTF-8", cancellationToken);
            }

            if (bytesToCopy == _frameBytesRemaining)
            {
                result = new WebSocketReceiveResult(bytesToCopy, messageType, _frameInProgress.Fin);
                if (_frameInProgress.Fin)
                {
                    _firstDataOpCode = null;
                }
                _frameInProgress = null;
                _dataUnmaskOffset = 0;
            }
            else
            {
                result = new WebSocketReceiveResult(bytesToCopy, messageType, false);
            }

            _frameBytesRemaining -= bytesToCopy;
            _receiveBufferBytes -= bytesToCopy;
            _receiveBufferOffset += bytesToCopy;

            return result;
        }