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; } }
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); }