예제 #1
0
        private async Task ReceivePayloadAsync(WebSocketReceiveBuffer buffer, Int32 payloadLength)
        {
            var offset = 0;

            while (payloadLength > 0)
            {
                var memory           = buffer.GetMemory(Math.Min(payloadLength, DefaultSegmentSize));
                var receiveByteCount = await ReceiveBufferAsync(memory.Slice(0, Math.Min(memory.Length, payloadLength)));

                if (m_receiveHeader.Mask != 0)   // Apply the mask to the payload we received so far
                {
                    ApplyMask(m_receiveHeader.Mask, memory.Slice(0, receiveByteCount).Span, offset);
                }

                buffer.Advance(receiveByteCount);
                payloadLength -= receiveByteCount;
                offset        += receiveByteCount;
            }
        }
예제 #2
0
        private async Task ReceiveHeaderAsync(WebSocketReceiveBuffer buffer)
        {
            var memory        = buffer.GetMemory(MaxHeaderSize).Slice(0, MaxHeaderSize);
            var receivedSize  = 0;
            var remainingSize = 2;

Receive:
            while (remainingSize > 0)
            {
                var byteCount = await ReceiveBufferAsync(memory.Slice(receivedSize, remainingSize));

                remainingSize -= byteCount;
                receivedSize  += byteCount;
            }

            var headerSize = 2;
            var masked     = (memory.Span[1] & 0b1000_0000) != 0;

            m_receiveHeader.Mask          = 0;
            m_receiveHeader.Fin           = (memory.Span[0] & 0b1000_0000) != 0;
            m_receiveHeader.Compressed    = (memory.Span[0] & 0b0100_0000) != 0;
            m_receiveHeader.Opcode        = (MessageOpcode)(memory.Span[0] & 0b0000_1111);
            m_receiveHeader.PayloadLength = memory.Span[1] & 0b0111_1111;

            buffer.Compressed = m_receiveHeader.Compressed;
            buffer.Type       = (WebSocketMessageType)m_receiveHeader.Opcode;

            if (masked)
            {
                headerSize += 4;
            }

            if (m_receiveHeader.PayloadLength == 126)
            {
                headerSize += 2;
            }
            else if (m_receiveHeader.PayloadLength == 127)
            {
                headerSize += 8;
            }

            if (receivedSize < headerSize)
            {
                remainingSize = headerSize - receivedSize;
                goto Receive; // More data is needed
            }

            // Read the remainder of the payload length, if necessary
            if (m_receiveHeader.PayloadLength == 126)
            {
                m_receiveHeader.PayloadLength = (memory.Span[2] << 8) | memory.Span[3];
            }
            else if (m_receiveHeader.PayloadLength == 127)
            {
                m_receiveHeader.PayloadLength = 0;

                for (var i = 0; i < 8; i++)
                {
                    m_receiveHeader.PayloadLength = (m_receiveHeader.PayloadLength << 8) | memory.Span[2 + i];
                }
            }

            if (masked)
            {
                m_receiveHeader.Mask = Unsafe.As <Byte, Int32>(ref memory.Span[headerSize - 4]);
            }

            WebSocketsEventSource.Log.Receive(Id,
                                              m_receiveHeader.Opcode,
                                              m_receiveHeader.PayloadLength,
                                              m_receiveHeader.Compressed,
                                              m_receiveHeader.Fin);
        }