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(); } }
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); }
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); }