Example #1
0
        public async Task <WSFrame> SendFrame(WSFrame frame, CancellationToken cancellationToken)
        {
            try {
                await semaphore.WaitAsync();

                var fragment = frame.Fragment;

                var frameHeader = new WSFrameHeader {
                    Mask   = true,
                    Last   = frame.Last,
                    Code   = frame.Code,
                    Length = fragment.Length,
                };

                Logger.Debug($"SendFrame");

                await SendFrameHeader(frameHeader, cancellationToken);

                Logger.Debug($"SendFrame (header complete)", new {
                    Header = frameHeader,
                });

                SendPayload(fragment.GetSegment());

                return(frame);
            }
            finally {
                semaphore.Release();
            }
        }
Example #2
0
        private async Task <WSFrameHeader> ReadFrameHeader(CancellationToken cancellationToken)
        {
            Array.Clear(frame, 0, 2);
            Array.Clear(frameMask, 0, 4);
            Array.Clear(frameLength, 0, 8);

            await Stream.ReadAsync(frame, 0, 2);

            var last = (frame[0] & WSConsts.MSB) != 0;
            var mask = (frame[1] & WSConsts.MSB) != 0;
            var rsv0 = (frame[0] & WSConsts.RSV0) != 0;
            var rsv1 = (frame[0] & WSConsts.RSV1) != 0;
            var rsv2 = (frame[0] & WSConsts.RSV2) != 0;

            var code   = frame[0] & WSConsts.CodeMask;
            var length = frame[1] & WSConsts.LengthMask;

            ResetMask();

            if (mask)
            {
                await Stream.ReadAsync(frameMask, 0, 4, cancellationToken);
            }

            switch (length)
            {
            case WSConsts.UInt16Flag:
                await Stream.ReadAsync(frameLength, 6, 2, cancellationToken);

                length = 0;

                DecodeLength(ref length);
                break;

            case WSConsts.UInt64Flag:
                await Stream.ReadAsync(frameLength, 0, 8, cancellationToken);

                length = 0;

                DecodeLength(ref length);
                break;
            }

            var header = new WSFrameHeader {
                Last   = last,
                Mask   = mask,
                Code   = code,
                RSV0   = rsv0,
                RSV1   = rsv1,
                RSV2   = rsv2,
                Length = length,
            };

            return(header);
        }
Example #3
0
        private async Task <WSFrameHeader> SendFrameHeader(WSFrameHeader frameHeader, CancellationToken cancellationToken)
        {
            Array.Clear(frame, 0, 2);
            Array.Clear(frameMask, 0, 4);
            Array.Clear(frameLength, 0, 8);

            var frameHeaderLength = GetLength(frameHeader.Length);

            var frame0 = 0;

            if (frameHeader.Last)
            {
                frame0 |= WSConsts.MSB;
            }

            if (frameHeader.RSV0)
            {
                frame0 |= WSConsts.RSV0;
            }

            if (frameHeader.RSV1)
            {
                frame0 |= WSConsts.RSV1;
            }

            if (frameHeader.RSV2)
            {
                frame0 |= WSConsts.RSV2;
            }

            frame0 |= frameHeader.Code & WSConsts.CodeMask;

            var frame1 = 0;

            if (frameHeader.Mask)
            {
                frame1 |= WSConsts.MSB;
            }

            frame1 |= frameHeaderLength & WSConsts.LengthMask;

            frame[0] = (byte)frame0;
            frame[1] = (byte)frame1;

            await Stream.WriteAsync(frame, 0, 2, cancellationToken);

            ResetMask();

            if (frameHeader.Mask)
            {
                CreateMask();

                await Stream.WriteAsync(frameMask, 0, 4, cancellationToken);
            }

            EncodeLength(frameHeader.Length);

            switch (frameHeaderLength)
            {
            case WSConsts.UInt16Flag:
                await Stream.WriteAsync(frameLength, 6, 2, cancellationToken);

                break;

            case WSConsts.UInt64Flag:
                await Stream.WriteAsync(frameLength, 0, 8, cancellationToken);

                break;
            }

            return(frameHeader);
        }