public static Task SendControlFrame(Synchronized <Stream> stream, ControlFrame frame) { return(SendFixedFrame(stream, frame.FrameType.ToControlFrameOpcode(), frame.Payload.Length, false, (buffer, appDataOffset) => { Buffer.BlockCopy(frame.Payload, 0, buffer, appDataOffset, frame.Payload.Length); })); }
public WebSocketSession(Stream stream, string requestUrl, IPEndPoint remoteAddress) { RequestUrl = requestUrl; RemoteEndPoint = remoteAddress; OutputStream = new Synchronized <Stream>(stream); InputStream = new Synchronized <Stream>(stream); }
protected override void Dispose(bool disposing) { if (UnderlyingHolder != null) { UnderlyingHolder.Dispose(); UnderlyingHolder = null; } base.Dispose(disposing); }
public WebSocketInputStream(WebSocketProtocol.FrameHeader initialHeader, Synchronized <Stream> .LockHolder underlyingHolder) { if (!underlyingHolder.LockedObject.CanRead) { throw new ArgumentException("Need readable Stream", "underlying"); } Underlying = underlyingHolder.LockedObject; UnderlyingHolder = underlyingHolder; BeginReadingFrame(initialHeader); }
public static async Task SendStream(Synchronized <Stream> sSocketStream, Stream dataStream, bool masking) { using (var socketStreamHolder = await sSocketStream) { var socketStream = socketStreamHolder.LockedObject; int appDataOffset; byte[] header, maskData; BuildFrameHeader(FrameOpcode.Binary, checked ((int)dataStream.Length), masking, out maskData, out header, out appDataOffset, bareHeader: true); await socketStream.WriteAsync(header, 0, header.Length); if (masking) { socketStream = new MaskingStream(socketStream, maskData); } await dataStream.CopyToAsync(socketStream); } }
private static async Task SendFixedFrame(Synchronized <Stream> sStream, FrameOpcode opcode, int appDataLength, bool masking, Action <byte[], int> dataWriter) { int appDataOffset; byte[] buffer, maskData; BuildFrameHeader(opcode, appDataLength, masking, out maskData, out buffer, out appDataOffset, bareHeader: false); dataWriter(buffer, appDataOffset); if (masking) { for (int i = 0; i < appDataLength; i++) { buffer[i + appDataOffset] ^= maskData[i % 4]; } } using (var streamHolder = await sStream) await streamHolder.LockedObject.WriteAsync(buffer, 0, buffer.Length); }
internal LockHolder(Synchronized <T> parent) { Parent = parent; }
public static async Task <object> ReadFrameGroupLockAcquired(Synchronized <Stream> .LockHolder streamHolder, Func <ControlFrame, Task> controlFrameHandler, CancellationToken token, bool loop = true) { var stream = streamHolder.LockedObject; var textFragments = new List <byte[]>(1); do { var header = await ReadFrameHeader(stream, token); switch (header.Opcode) { case FrameOpcode.Binary: if (textFragments.Count > 0) { throw new InvalidDataException(); } return(new WebSocketInputStream(header, streamHolder)); case FrameOpcode.Continuation: // we don't have to expect that the client breaks the protocol // if this continues binary, we already returned the stream case FrameOpcode.Text: var streamAfterMasking = header.IsMasked ? new MaskingStream(stream, header.MaskData) : stream; var buffer = await streamAfterMasking.ReadAllBytesAsync(header.PayloadLength, token); textFragments.Add(buffer); if (header.GroupIsComplete) { if (textFragments.Count == 1) { streamHolder.Dispose(); return(Encoding.UTF8.GetString(buffer)); } var finalBuffer = new byte[textFragments.Sum(array => array.Length)]; int offset = 0; foreach (var part in textFragments) { Buffer.BlockCopy(part, 0, finalBuffer, offset, part.Length); offset += part.Length; } streamHolder.Dispose(); return(Encoding.UTF8.GetString(finalBuffer)); } break; case FrameOpcode.Ping: case FrameOpcode.Pong: case FrameOpcode.Close: await HandleControlFrame(header, stream, controlFrameHandler, token); if (header.Opcode == FrameOpcode.Close) { return(null); } break; default: throw new InvalidDataException("unknown opcode"); } } while (loop); streamHolder.Dispose(); return(null); }
public static async Task <object> ReadFrameGroup(Synchronized <Stream> stream, Func <ControlFrame, Task> controlFrameHandler, CancellationToken token) { return(await ReadFrameGroupLockAcquired(await stream, controlFrameHandler, token)); }
public static Task SendByteArrayFrame(Synchronized <Stream> stream, byte[] data, int offset, int length, bool masking) { return(SendFixedFrame(stream, FrameOpcode.Binary, length, masking, (buffer, appDataOffset) => { Buffer.BlockCopy(data, offset, buffer, appDataOffset, length); })); }
public static Task SendTextFrame(Synchronized <Stream> stream, string message, bool masking) { return(SendFixedFrame(stream, FrameOpcode.Text, Encoding.UTF8.GetByteCount(message), masking, (buffer, appDataOffset) => { Encoding.UTF8.GetBytes(message, 0, message.Length, buffer, appDataOffset); })); }