Пример #1
0
        public static void ProcessFrame(FrameType frameType, byte[] data, Action <string> onMessage, Action onClose, Action <byte[]> onBinary, Action <byte[]> onPing, Action <byte[]> onPong)
        {
            switch (frameType)
            {
            case FrameType.Close:
                if (data.Length == 1 || data.Length > 125)
                {
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                if (data.Length >= 2)
                {
                    //var closeCode = (ushort)data.Take(2).ToArray().ToLittleEndianInt();
                    byte[] _codeAry = new byte[] {
                        data[0],
                        data[1]
                    };
                    var closeCode = (ushort)IntExtensions.ToLittleEndianInt(_codeAry);

                    if (                            //!WebSocketStatusCodes.ValidCloseCodes.Contains(closeCode)
                        -1 == Array.IndexOf(WebSocketStatusCodes.ValidCloseCodes, closeCode) &&
                        (closeCode < 3000 || closeCode > 4999))
                    {
                        throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                    }
                }
                if (data.Length > 2)
                {
                    //ReadUTF8PayloadData(data.Skip(2).ToArray());
                    var _dataAry = LinqExtensions.SkipTakeToArray(data, 2);
                    ReadUTF8PayloadData(_dataAry);
                }

                onClose();
                break;

            case FrameType.Binary:
                onBinary(data);
                break;

            case FrameType.Ping:
                onPing(data);
                break;

            case FrameType.Pong:
                onPong(data);
                break;

            case FrameType.Text:
                onMessage(ReadUTF8PayloadData(data));
                break;

            default:
                FleckLog.Debug("Received unhandled " + frameType);
                break;
            }
        }
Пример #2
0
        public static void ReceiveData(List <byte> data, ReadState readState, Action <FrameType, byte[]> processFrame)
        {
            while (data.Count >= 2)
            {
                var isFinal      = (data[0] & 128) != 0;
                var reservedBits = (data[0] & 112);
                var frameType    = (FrameType)(data[0] & 15);
                var isMasked     = (data[1] & 128) != 0;
                var length       = (data[1] & 127);


                if (!isMasked ||
                    !Enum.IsDefined(typeof(FrameType), frameType) ||
                    reservedBits != 0 ||             //Must be zero per spec 5.2
                    (frameType == FrameType.Continuation && !readState.FrameType.HasValue))
                {
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                var index = 2;
                int payloadLength;

                if (length == 127)
                {
                    if (data.Count < index + 8)
                    {
                        return;                         //Not complete
                    }
                    //payloadLength = data.Skip(index).Take(8).ToArray().ToLittleEndianInt();
                    var _data = LinqExtensions.SkipTakeToArray(
                        data.ToArray(),
                        index,
                        8
                        );
                    payloadLength = IntExtensions.ToLittleEndianInt(_data);

                    index += 8;
                }
                else if (length == 126)
                {
                    if (data.Count < index + 2)
                    {
                        return;                         //Not complete
                    }
                    //payloadLength = data.Skip(index).Take(2).ToArray().ToLittleEndianInt();
                    var _data = LinqExtensions.SkipTakeToArray(
                        data.ToArray(),
                        index,
                        2
                        );
                    payloadLength = IntExtensions.ToLittleEndianInt(_data);

                    index += 2;
                }
                else
                {
                    payloadLength = length;
                }

                if (data.Count < index + 4)
                {
                    return;                     //Not complete
                }
                //var maskBytes = data.Skip(index).Take(4).ToArray();
                var maskBytes = LinqExtensions.SkipTakeToArray(
                    data.ToArray(),
                    index,
                    4
                    );

                index += 4;


                if (data.Count < index + payloadLength)
                {
                    return;                     //Not complete
                }
                //var payload = data
                //.Skip(index)
                //.Take(payloadLength)
                //.Select((x, idx) => (byte)(x ^ maskBytes[idx % 4]));

                var payload = LinqExtensions.SkipTakeToArray(
                    data.ToArray(),
                    index,
                    payloadLength,
                    (x, idx) => (byte)(x ^ maskBytes[idx % 4])
                    );

                readState.Data.AddRange(payload);
                data.RemoveRange(0, index + payloadLength);

                if (frameType != FrameType.Continuation)
                {
                    readState.FrameType = frameType;
                }

                if (isFinal && readState.FrameType.HasValue)
                {
                    var stateData      = readState.Data.ToArray();
                    var stateFrameType = readState.FrameType;
                    readState.Clear();

                    processFrame(stateFrameType.Value, stateData);
                }
            }
        }