示例#1
0
        static Header ReadHeader(Config config, byte[] buffer, bool opCodeContinuation = false)
        {
            (Connection conn, int maxMessageSize, bool expectMask, ConcurrentQueue <Message> queue, BufferPool bufferPool) = config;
            Stream stream = conn.stream;
            var    header = new Header();

            // read 2
            header.offset = ReadHelper.Read(stream, buffer, header.offset, Constants.HeaderMinSize);
            // log after first blocking call
            Log.Verbose($"Message From {conn}");

            if (MessageProcessor.NeedToReadShortLength(buffer))
            {
                header.offset = ReadHelper.Read(stream, buffer, header.offset, Constants.ShortLength);
            }
            if (MessageProcessor.NeedToReadLongLength(buffer))
            {
                header.offset = ReadHelper.Read(stream, buffer, header.offset, Constants.LongLength);
            }

            Log.DumpBuffer($"Raw Header", buffer, 0, header.offset);

            MessageProcessor.ValidateHeader(buffer, maxMessageSize, expectMask, opCodeContinuation);

            if (expectMask)
            {
                header.offset = ReadHelper.Read(stream, buffer, header.offset, Constants.MaskSize);
            }

            header.opcode        = MessageProcessor.GetOpcode(buffer);
            header.payloadLength = MessageProcessor.GetPayloadLength(buffer);
            header.finished      = MessageProcessor.Finished(buffer);

            Log.Verbose($"Header ln:{header.payloadLength} op:{header.opcode} mask:{expectMask}");

            return(header);
        }
示例#2
0
        static void ReadOneMessage(Config config, byte[] buffer)
        {
            (Connection conn, int maxMessageSize, bool expectMask, ConcurrentQueue <Message> queue, BufferPool bufferPool) = config;
            Stream stream = conn.stream;

            Header header = ReadHeader(config, buffer);

            int msgOffset = header.offset;

            header.offset = ReadHelper.Read(stream, buffer, header.offset, header.payloadLength);

            if (header.finished)
            {
                switch (header.opcode)
                {
                case 2:
                    HandleArrayMessage(config, buffer, msgOffset, header.payloadLength);
                    break;

                case 8:
                    HandleCloseMessage(config, buffer, msgOffset, header.payloadLength);
                    break;
                }
            }
            else
            {
                // todo cache this to avoid allocations
                var fragments = new Queue <ArrayBuffer>();
                fragments.Enqueue(CopyMessageToBuffer(bufferPool, expectMask, buffer, msgOffset, header.payloadLength));
                int totalSize = header.payloadLength;

                while (!header.finished)
                {
                    header = ReadHeader(config, buffer, opCodeContinuation: true);

                    msgOffset     = header.offset;
                    header.offset = ReadHelper.Read(stream, buffer, header.offset, header.payloadLength);
                    fragments.Enqueue(CopyMessageToBuffer(bufferPool, expectMask, buffer, msgOffset, header.payloadLength));

                    totalSize += header.payloadLength;
                    MessageProcessor.ThrowIfMsgLengthTooLong(totalSize, maxMessageSize);
                }


                ArrayBuffer msg = bufferPool.Take(totalSize);
                msg.count = 0;
                while (fragments.Count > 0)
                {
                    ArrayBuffer part = fragments.Dequeue();

                    part.CopyTo(msg.array, msg.count);
                    msg.count += part.count;

                    part.Release();
                }

                // dump after mask off
                Log.DumpBuffer($"Message", msg);

                queue.Enqueue(new Message(conn.connId, msg));
            }
        }