public WebSocketDataStream(Stream innerStream, StreamReadInfo initialReadInfo, Func <Task <StreamReadInfo> > readInfoFunc, Func <Task> consumedAction) { _innerStream = innerStream; _readInfo = initialReadInfo; _readInfoFunc = readInfoFunc; _consumedAction = consumedAction; }
public async Task <WebSocketMessage> Read(CancellationToken cancellationToken) { WebSocketFrameHeader header; StreamReadInfo readInfo = null; await _waitHandle.WaitAsync(cancellationToken).ConfigureAwait(false); if (_isClosed) { return(null); } header = await ReadHeader(cancellationToken).ConfigureAwait(false); if (header == null) { return(null); } readInfo = await GetStreamReadInfo(header, cancellationToken).ConfigureAwait(false); var msg = CreateMessage(header, readInfo, _waitHandle); if (msg.Opcode == Opcode.Close) { _isClosed = true; } return(msg); }
public override async Task <int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { var position = offset; var bytesRead = 0; while (bytesRead < count && _readInfo.PayloadLength > 0) { var toread = Math.Min((ulong)(count - bytesRead), _readInfo.PayloadLength); toread = Math.Min(toread, int.MaxValue); var read = await _innerStream.ReadAsync(buffer, position, (int)toread, cancellationToken).ConfigureAwait(false); bytesRead += read; _readInfo.ReducePayloadLength(Convert.ToUInt32(read)); if (_readInfo.MaskingKey.Length > 0) { var max = position + (int)toread; for (var pos = position; pos < max; pos++) { buffer[pos] = (byte)(buffer[pos] ^ _readInfo.MaskingKey[pos % 4]); } } position += read; _position = position; if (_readInfo.PayloadLength == 0) { if (!_readInfo.IsFinal) { try { _readInfo = await _readInfoFunc().ConfigureAwait(false); } catch { Debug.WriteLine("Failed at position {0}", Position); } } else { await _consumedAction().ConfigureAwait(false); } } } return(bytesRead); }
private WebSocketMessage CreateMessage(WebSocketFrameHeader header, StreamReadInfo readInfo, SemaphoreSlim waitHandle) { switch (header.Opcode) { case Opcode.Cont: throw new WebSocketException(CloseStatusCode.InconsistentData, "Did not expect continuation frame."); default: case Opcode.Close: case Opcode.Text: case Opcode.Binary: return(new FragmentedMessage(header.Opcode, _innerStream, readInfo, GetStreamReadInfo, waitHandle, _fragmentLength)); } }
public FragmentedMessage(Opcode opcode, Stream stream, StreamReadInfo initialRead, Func <Task <StreamReadInfo> > payloadFunc, SemaphoreSlim waitHandle, int fragmentLength) : base(opcode, waitHandle, fragmentLength) { _stream = new WebSocketDataStream(stream, initialRead, payloadFunc, Consume); Text = new StreamReader(_stream, true); }