public async void TestReadWriteAsync() { using (var stream = new CompressedStream(new DummyNetworkStream())) { string command = "A00000001 APPEND INBOX (\\Seen \\Draft) {4096+}\r\nFrom: Sample Sender <*****@*****.**>\r\nTo: Sample Recipient <*****@*****.**>\r\nSubject: This is a test message...\r\nDate: Mon, 22 Oct 2018 18:22:56 EDT\r\nMessage-Id: <*****@*****.**>\r\n\r\nTesting... 1. 2. 3.\r\nTesting.\r\nOver and out.\r\n"; var output = Encoding.ASCII.GetBytes(command); const int compressedLength = 221; var buffer = new byte[1024]; int n; await stream.WriteAsync(output, 0, output.Length); await stream.FlushAsync(); Assert.AreEqual(compressedLength, stream.BaseStream.Position, "Compressed output length"); stream.BaseStream.Position = 0; n = await stream.ReadAsync(buffer, 0, buffer.Length); Assert.AreEqual(output.Length, n, "Decompressed input length"); var text = Encoding.ASCII.GetString(buffer, 0, n); Assert.AreEqual(command, text); } }
internal async Task ListenAsync() { await Task.Yield(); var buff = new byte[BUFFER_SIZE]; var buffseg = new ArraySegment <byte>(buff); byte[] resultbuff = null; WebSocketReceiveResult result = null; SocketCloseEventArgs close = null; var token = Token; try { while (!token.IsCancellationRequested && Socket.State == WebSocketState.Open) { using (var ms = new MemoryStream()) { do { result = await Socket.ReceiveAsync(buffseg, token).ConfigureAwait(false); if (result.MessageType == WebSocketMessageType.Close) { var cc = result.CloseStatus != null ? (int)result.CloseStatus.Value : -1; close = new SocketCloseEventArgs(null) { CloseCode = cc, CloseMessage = result.CloseStatusDescription }; } else { ms.Write(buff, 0, result.Count); } }while (!result.EndOfMessage); resultbuff = ms.ToArray(); } if (close != null) { break; } var resultstr = ""; if (result.MessageType == WebSocketMessageType.Binary) { if (resultbuff[0] == 0x78) { await CompressedStream.WriteAsync(resultbuff, 2, resultbuff.Length - 2).ConfigureAwait(false); } else { await CompressedStream.WriteAsync(resultbuff, 0, resultbuff.Length).ConfigureAwait(false); } await CompressedStream.FlushAsync().ConfigureAwait(false); CompressedStream.Position = 0; // partial credit to FiniteReality // overall idea is their // I tuned the finer details // -Emzi var sfix = BitConverter.ToUInt16(resultbuff, resultbuff.Length - 2); if (sfix != ZLIB_STREAM_SUFFIX) { using (var zlib = new DeflateStream(CompressedStream, CompressionMode.Decompress, true)) { await zlib.CopyToAsync(DecompressedStream).ConfigureAwait(false); } } else { await StreamDecompressor.CopyToAsync(DecompressedStream).ConfigureAwait(false); } resultbuff = DecompressedStream.ToArray(); DecompressedStream.Position = 0; DecompressedStream.SetLength(0); CompressedStream.Position = 0; CompressedStream.SetLength(0); } resultstr = UTF8.GetString(resultbuff, 0, resultbuff.Length); await CallOnMessageAsync(resultstr).ConfigureAwait(false); } } catch (Exception e) { close = new SocketCloseEventArgs(null) { CloseCode = -1, CloseMessage = e.Message }; } await DisconnectAsync(close).ConfigureAwait(false); }