Esempio n. 1
0
        internal async Task <int> ReadToBufferAsync()
        {
            var bufferRemaining = readBuffer.Length - readBufferOffset;

            if (bufferRemaining == 0)
            {
                BufferUtils.Expand(ref readBuffer, readBuffer.Length); // double buffer
                bufferRemaining = readBuffer.Length - readBufferOffset;
            }

            try
            {
                var bytesRead = await Stream.ReadAsync(readBuffer, readBufferOffset, bufferRemaining).ConfigureAwait(false);

                readBufferOffset += bytesRead;
                return(bytesRead);
            }
            catch (Exception e)
            {
                throw new SessionStreamException("Exception while reading from stream", e);
            }
        }
Esempio n. 2
0
        bool TryDecodeNextMessage(out OpCode opCode, out byte[] messagePayload)
        {
            while (true)
            {
                switch (decodeState)
                {
                case DecodeState.DecodeHeader:
                    if (FrameDecoder.TryDecodeHeader(readBuffer, ref dataStart, readBufferOffset, out isFin, out frameOpCode, out isMasked, out framePayloadLength, mask))
                    {
                        decodeState = DecodeState.DecodePayload;

                        switch (frameOpCode)
                        {
                        case OpCode.Continuation:
                            if (framePayloadLength > 0)
                            {
                                BufferUtils.Expand(ref messageBuffer, framePayloadLength);         //TODO: limit, sanity guard
                            }
                            break;

                        case OpCode.Text:
                        case OpCode.Binary:
                            messageOpCode       = frameOpCode;
                            messageBuffer       = new byte[framePayloadLength];
                            messageBufferOffset = 0;
                            break;

                        case OpCode.Close:
                        case OpCode.Ping:
                        case OpCode.Pong:
                            if (!isFin)
                            {
                                throw new WebSocketException("Control frame cannot be fragmented");
                            }
                            break;
                        }

                        continue;
                    }
                    break;

                case DecodeState.DecodePayload:
                    var decodeStart = dataStart;
                    if (FrameDecoder.TryDecodePayload(readBuffer, ref dataStart, readBufferOffset, framePayloadLength, isMasked, mask))
                    {
                        decodeState = DecodeState.DecodeHeader;

                        switch (frameOpCode)
                        {
                        case OpCode.Continuation:
                        case OpCode.Text:
                        case OpCode.Binary:
                            Array.Copy(readBuffer, decodeStart, messageBuffer, messageBufferOffset, framePayloadLength);
                            CompactReadBuffer(ref dataStart);
                            if (isFin)
                            {
                                opCode              = messageOpCode;
                                messagePayload      = messageBuffer;
                                messageBuffer       = null;
                                messageBufferOffset = 0;
                                return(true);
                            }
                            else
                            {
                                messageBufferOffset += framePayloadLength;
                                continue;
                            }

                        case OpCode.Close:
                        case OpCode.Ping:
                        case OpCode.Pong:
                            opCode         = frameOpCode;
                            messagePayload = new byte[framePayloadLength];
                            Array.Copy(readBuffer, decodeStart, messagePayload, 0, framePayloadLength);
                            CompactReadBuffer(ref dataStart);
                            return(true);        // must be Fin
                        }
                    }
                    break;
                }

                opCode         = OpCode.Continuation;
                messagePayload = null;
                return(false);
            }
        }