public override void OnReceive(ReadOnlySpan <byte> data)
        {
            base.OnReceive(data);
            Span <byte> headerSpan = headerPayload;

            while (RecvBuffer.Peek(headerSpan) == 4)
            {
                if (BitConverter.IsLittleEndian)
                {
                    headerSpan.Reverse();
                }

                var payloadLength = BitConverter.ToInt32(headerSpan);
                if (payloadLength > payload.Length)
                {
                    throw new IndexOutOfRangeException("not enough buffer for message");
                }

                if (payloadLength + 4 <= RecvBuffer.Length)
                {
                    RecvBuffer.Skip(4);
                    Span <byte> messageSpan = payload;
                    messageSpan = messageSpan.Slice(0, payloadLength);
                    var count = RecvBuffer.Take(messageSpan);
                    OnNewMessage?.Invoke(messageSpan, count);
                }
                else
                {
                    break;
                }
            }
        }
        public override void OnReceive(ReadOnlySpan <byte> data)
        {
            base.OnReceive(data);
            Span <byte> header = headerPayload;

            while (streamReadBytesLeft == 0 && RecvBuffer.Peek(header) == 12)
            {
                // use network endian
                var messageType   = BinaryPrimitives.ReadInt32BigEndian(header);
                var payloadLength = BinaryPrimitives.ReadInt64BigEndian(header.Slice(4));
                if (messageType == MessageType.Message)
                {
                    if (payloadLength > payloadBuffer.Length)
                    {
                        throw new IndexOutOfRangeException(
                                  $"Message({payloadLength}) is too big to fit into the buffer({payloadBuffer.Length})");
                    }

                    if (payloadLength + 12 <= RecvBuffer.Length)
                    {
                        RecvBuffer.Skip(12);
                        Span <byte> messageSpan = payloadBuffer;
                        messageSpan = messageSpan.Slice(0, (int)payloadLength);
                        var count = RecvBuffer.Take(messageSpan);
                        OnNewMessage?.Invoke(messageSpan, count);
                    }
                    else
                    {
                        break;
                    }
                }
                else if (messageType == MessageType.ByteStream)
                {
                    if (memoryStream == null)
                    {
                        memoryStream = new MemoryStream(1024 * 1024 * 4);
                    }

                    memoryStream.SetLength(0);
                    memoryStream.Seek(0, SeekOrigin.Begin);
                    streamReadBytesLeft = payloadLength;
                    RecvBuffer.Skip(12);

                    DrainStreamPayload();
                }
            }

            while (streamReadBytesLeft > 0)
            {
                if (DrainStreamPayload() == 0)
                {
                    break;
                }
            }
        }