public async Task CanCancelFlushAsyncWithCancelPendingFlushStreamFlushAsyncThrows() { var stream = new CancelledWritesStream(); stream.WaitForWriteTask.TrySetResult(null); PipeWriter writer = PipeWriter.Create(stream); writer.WriteEmpty(10); ValueTask <FlushResult> task = writer.FlushAsync(); Assert.False(task.IsCompleted); writer.CancelPendingFlush(); stream.WaitForFlushTask.TrySetResult(null); FlushResult result = await task; Assert.True(result.IsCanceled); writer.Complete(); }
public async Task CanCancelFlushAsyncWithCancellationTokenWhenStreamWriteAsyncThrows() { var stream = new CancelledWritesStream(); stream.WaitForFlushTask.TrySetResult(null); var cts = new CancellationTokenSource(); PipeWriter writer = PipeWriter.Create(stream); writer.WriteEmpty(10); ValueTask <FlushResult> task = writer.FlushAsync(cts.Token); Assert.False(task.IsCompleted); cts.Cancel(); stream.WaitForWriteTask.TrySetResult(null); await Assert.ThrowsAsync <OperationCanceledException>(async() => await task); writer.Complete(); }
public async Task WriteMessageAsync_HasCustomCompressionLevel_WriteCompressedDataWithLevel() { // Arrange var mockCompressionProvider = new MockCompressionProvider(); var httpContext = new DefaultHttpContext(); httpContext.Request.Headers[GrpcProtocolConstants.MessageAcceptEncodingHeader] = "Mock"; var context = HttpContextServerCallContextHelper.CreateServerCallContext( httpContext, responseCompressionAlgorithm: "Mock", responseCompressionLevel: System.IO.Compression.CompressionLevel.Optimal, compressionProviders: new List <ICompressionProvider> { mockCompressionProvider }); context.Initialize(); var ms = new MemoryStream(); var pipeWriter = PipeWriter.Create(ms); // Act await pipeWriter.WriteMessageAsync(new TestData(new byte[] { 0x10 }), context, TestDataMarshaller.ContextualSerializer, canFlush : true); // Assert Assert.AreEqual(System.IO.Compression.CompressionLevel.Optimal, mockCompressionProvider.ArgumentCompression); var messageData = ms.ToArray(); Assert.AreEqual(1, messageData[0]); // compression Assert.AreEqual(21, messageData[4]); // message length byte[] result = Decompress(mockCompressionProvider, messageData); Assert.AreEqual(1, result.Length); Assert.AreEqual(0x10, result[0]); }
public async Task WriteMessageAsync_EmptyMessage_WriteMessageWithNoData() { // Arrange var ms = new MemoryStream(); var pipeWriter = PipeWriter.Create(ms); // Act await pipeWriter.WriteMessageAsync(Array.Empty <byte>(), TestServerCallContext, Marshaller.ContextualSerializer, canFlush : true); // Assert var messageData = ms.ToArray(); CollectionAssert.AreEqual( new byte[] { 0x00, // compression = 0 0x00, 0x00, 0x00, 0x00, // length = 0 }, messageData); }
public async Task SaveMemoryTable(MemoryTable skipList) { using var fs = System.IO.File.Open(_fileName, System.IO.FileMode.CreateNew); var pipeWriter = PipeWriter.Create(fs); var iterator = skipList.GetEnumerator(); if (!iterator.MoveNext()) { throw new ArgumentOutOfRangeException("Empty iterator nothing to save"); } var itemCount = 0; WriteBlocks(pipeWriter, iterator, ref itemCount); await pipeWriter.FlushAsync(); WriteTOC(pipeWriter, _metaData.FirstKey.Span, _metaData.LastKey.Span, itemCount); await pipeWriter.FlushAsync(); await pipeWriter.CompleteAsync(); }
public static void WriteMessage <T>(Stream stream, T message, string?compressionEncoding = null, List <ICompressionProvider>?compressionProviders = null) where T : class, IMessage { compressionProviders = compressionProviders ?? new List <ICompressionProvider> { new GzipCompressionProvider(CompressionLevel.Fastest) }; var pipeWriter = PipeWriter.Create(stream); var httpContext = new DefaultHttpContext(); httpContext.Request.Headers[GrpcProtocolConstants.MessageAcceptEncodingHeader] = compressionEncoding; var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext( httpContext: httpContext, compressionProviders: compressionProviders, responseCompressionAlgorithm: compressionEncoding); serverCallContext.Initialize(); pipeWriter.WriteMessageAsync(message, serverCallContext, (r, c) => c.Complete(r.ToByteArray()), canFlush: true).GetAwaiter().GetResult(); stream.Seek(0, SeekOrigin.Begin); }
public async Task WriteStreamedMessageAsync_OneByteMessage_WriteData() { // Arrange var ms = new MemoryStream(); var pipeWriter = PipeWriter.Create(ms); // Act await pipeWriter.WriteStreamedMessageAsync(new TestData(new byte[] { 0x10 }), HttpContextServerCallContextHelper.CreateServerCallContext(), TestDataMarshaller.ContextualSerializer); // Assert var messageData = ms.ToArray(); CollectionAssert.AreEqual( new byte[] { 0x00, // compression = 0 0x00, 0x00, 0x00, 0x01, // length = 1 0x10 }, messageData); }
public async Task WriteAsyncThrowsDuringMultiSegmentWriteCompleteReturnsAllMemory() { using (var pool = new DisposeTrackingBufferPool()) { var stream = new ThrowAfterNWritesStream(1); var options = new StreamPipeWriterOptions(pool); PipeWriter writer = PipeWriter.Create(stream, options); writer.WriteEmpty(pool.MaxBufferSize); writer.WriteEmpty(pool.MaxBufferSize); writer.WriteEmpty(pool.MaxBufferSize); Assert.Equal(3, pool.CurrentlyRentedBlocks); Assert.Equal(0, pool.DisposedBlocks); await Assert.ThrowsAsync <InvalidOperationException>(async() => await writer.FlushAsync()); Assert.Equal(2, pool.CurrentlyRentedBlocks); Assert.Equal(1, pool.DisposedBlocks); writer.Complete(); Assert.Equal(0, pool.CurrentlyRentedBlocks); Assert.Equal(3, pool.DisposedBlocks); } }
public async Task WriteMessageAsync_OneByteMessage_WriteData() { // Arrange var ms = new MemoryStream(); var pipeWriter = PipeWriter.Create(ms); // Act await pipeWriter.WriteMessageAsync(new byte[] { 0x10 }, TestServerCallContext, flush : true); // Assert var messageData = ms.ToArray(); CollectionAssert.AreEqual( new byte[] { 0x00, // compression = 0 0x00, 0x00, 0x00, 0x01, // length = 1 0x10 }, messageData); }
public async Task WriteMessageAsync_HasCustomCompressionLevel_WriteCompressedDataWithLevel() { // Arrange var mockCompressionProvider = new MockCompressionProvider(); var serviceOptions = new GrpcServiceOptions { ResponseCompressionAlgorithm = "Mock", ResponseCompressionLevel = System.IO.Compression.CompressionLevel.Optimal, CompressionProviders = { mockCompressionProvider } }; var httpContext = new DefaultHttpContext(); httpContext.Request.Headers[GrpcProtocolConstants.MessageAcceptEncodingHeader] = "Mock"; var context = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext, serviceOptions); context.Initialize(); var ms = new MemoryStream(); var pipeWriter = PipeWriter.Create(ms); // Act await pipeWriter.WriteMessageAsync(new byte[] { 0x10 }, context, flush : true); // Assert Assert.AreEqual(System.IO.Compression.CompressionLevel.Optimal, mockCompressionProvider.ArgumentCompression); var messageData = ms.ToArray(); Assert.AreEqual(1, messageData[0]); // compression Assert.AreEqual(21, messageData[4]); // message length }
public async Task WriteMessageAsync_EmptyMessage_WriteMessageWithNoData() { // Arrange var ms = new MemoryStream(); var pipeWriter = new Base64PipeWriter(PipeWriter.Create(ms)); // Act await pipeWriter.WriteMessageAsync(new EchoRequest(), HttpContextServerCallContextHelper.CreateServerCallContext(), MarshallerEchoRequest.ContextualSerializer, canFlush : true); // Assert var base64 = Encoding.UTF8.GetString(ms.ToArray()); var messageData = Convert.FromBase64String(base64); CollectionAssert.AreEqual( new byte[] { 0x00, // compression = 0 0x00, 0x00, 0x00, 0x00, // length = 0 }, messageData); }
public async Task WriteAsync_BufferHintWriteOptions_DoesNotFlush() { // Arrange var ms = new MemoryStream(); var httpContext = new DefaultHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(new TestResponseBodyFeature(PipeWriter.Create(ms))); var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext); var writer = new HttpContextStreamWriter <HelloReply>(serverCallContext, MessageHelpers.ServiceMethod.ResponseMarshaller.ContextualSerializer); serverCallContext.WriteOptions = new WriteOptions(WriteFlags.BufferHint); // Act 1 await writer.WriteAsync(new HelloReply { Message = "Hello world 1" }); // Assert 1 Assert.AreEqual(0, ms.Length); // Act 2 await writer.WriteAsync(new HelloReply { Message = "Hello world 2" }); // Assert 2 Assert.AreEqual(0, ms.Length); await httpContext.Response.BodyWriter.FlushAsync(); ms.Seek(0, SeekOrigin.Begin); var pipeReader = PipeReader.Create(ms); var writtenMessage1 = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.AreEqual("Hello world 1", writtenMessage1 !.Message); var writtenMessage2 = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.AreEqual("Hello world 2", writtenMessage2 !.Message); }
public DuplexStreamPipe(Stream stream) { Input = PipeReader.Create(stream, s_readerOpts); Output = PipeWriter.Create(stream, s_writerOpts); }
public async Task OperationCancelledExceptionNotSwallowedIfNotThrownFromSpecifiedToken() { PipeWriter writer = PipeWriter.Create(new ThrowsOperationCanceledExceptionStream()); await Assert.ThrowsAsync <OperationCanceledException>(async() => await writer.WriteAsync(new byte[1])); }
public static PipeWriter AsPipeWriter(this Stream stream, StreamPipeWriterOptions?options = null) { return(PipeWriter.Create(stream, options)); }
public async Task <bool> ConnectAsync() { try { Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { NoDelay = ClientOption.NoDelay }; await Socket.ConnectAsync(new IPEndPoint(IPAddress.Parse(ClientOption.Ip), ClientOption.Port)); RemoteEndPoint = Socket.RemoteEndPoint; LocalEndPoint = Socket.LocalEndPoint; if (ClientOption.Security == SslProtocols.None) { Stream = new NetworkStream(Socket, true); Reader = PipeReader.Create(Stream); Writer = PipeWriter.Create(Stream); IsConnected = true; LogHelper.Info($"连接服务器[{ClientOption.Ip}:{ClientOption.Port}]成功"); OnConnected?.Invoke(this); ProcessReadAsync(); return(true); } else { ClientOption.SslClientAuthenticationOptions.RemoteCertificateValidationCallback = SSLValidationCallback; var sslStream = new SslStream(new NetworkStream(Socket, true), false); var cancelTokenSource = new CancellationTokenSource(); cancelTokenSource.CancelAfter(5000); return(await sslStream.AuthenticateAsClientAsync(ClientOption.SslClientAuthenticationOptions, cancelTokenSource.Token).ContinueWith(t => { if (sslStream.IsAuthenticated) { Stream = sslStream; Reader = PipeReader.Create(Stream); Writer = PipeWriter.Create(Stream); IsConnected = true; LogHelper.Info($"连接服务器[{ClientOption.Ip}:{ClientOption.Port}]成功"); OnConnected?.Invoke(this); ProcessReadAsync(); return true; } else { if (t.IsCanceled) { LogHelper.Error($"连接{RemoteEndPoint}证书验证超时,关闭连接"); } Close(); return false; } })); } } catch (Exception ex) { if (IsConnected) { Close(); } IsConnected = false; LogHelper.Error($"客户端异常:{ex}"); return(false); } }
/// <summary> /// 启动服务 /// </summary> /// <returns></returns> public virtual Task <bool> StartAysnc() { return(Task.Run(() => { bool isSuccess = false; try { if (ServerOption == null) { throw new ArgumentException("ServerOption服务配置尚未配置"); } IPEndPoint iPEndPoint = new IPEndPoint(ServerOption.Ip == "Any" ? IPAddress.Any : IPAddress.Parse(ServerOption.Ip), ServerOption.Port); if (ServerOption.ProtocolType == ProtocolType.Tcp) { #region TCP Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { NoDelay = ServerOption.NoDelay }; Socket.Bind(iPEndPoint); //开始监听 Socket.Listen(ServerOption.BackLog); //开启一个线程接收客户端连接 Task.Run(async() => { while (true) { var client = await Socket.AcceptAsync(); //构造客户端Session var session = new TSession { Socket = client, LocalEndPoint = client.LocalEndPoint, RemoteEndPoint = client.RemoteEndPoint }; //非SSL if (ServerOption.Security == SslProtocols.None) { //Socket转字节流对象 session.Stream = new NetworkStream(session.Socket, true); //字节流绑定到Pipe管道(高性能缓冲区) session.Reader = PipeReader.Create(session.Stream); //读取数据端 session.Writer = PipeWriter.Create(session.Stream); //发送数据端 //添加到Session容器 SessionContainer.Add(session); OnConnected?.Invoke(session); //开启一个线程异步接收这个连接的数据 ProcessReadAsync(session); } else//SSL { //绑定SSL认证回调 ServerOption.SslServerAuthenticationOptions.RemoteCertificateValidationCallback = SSLValidationCallback; //加密传输字节流 var sslStream = new SslStream(new NetworkStream(session.Socket, true), false); var cancelTokenSource = new CancellationTokenSource(); //SSL认证超时时间为5s cancelTokenSource.CancelAfter(5000); await sslStream.AuthenticateAsServerAsync(ServerOption.SslServerAuthenticationOptions, cancelTokenSource.Token).ContinueWith(t => { if (sslStream.IsAuthenticated) { //验证成功 session.Stream = sslStream; //字节流绑定到Pipe管道(高性能缓冲区) session.Reader = PipeReader.Create(session.Stream); //读取数据端 session.Writer = PipeWriter.Create(session.Stream); //发送数据端 //添加到Session容器 SessionContainer.Add(session); OnConnected?.Invoke(session); //开启一个线程异步接收这个连接的数据 ProcessReadAsync(session); } else { if (t.IsCanceled) { LogHelper.Error($"连接{session.RemoteEndPoint}证书验证超时,关闭连接"); } Close(session); } }); } } }); #endregion } else if (ServerOption.ProtocolType == ProtocolType.Udp) { #region UDP Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); Socket.Bind(iPEndPoint); EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0); var session = new TSession { Socket = Socket, LocalEndPoint = Socket.LocalEndPoint }; //异步接收这个连接的数据 Socket.BeginReceiveFrom(session.Data, 0, session.Data.Length, SocketFlags.None, ref remoteEP, UdpReceiveCallback, session); #endregion } else { throw new Exception("不支持的传输协议"); } isSuccess = true; } catch (Exception ex) { LogHelper.Error($"【{ServerOption.Port}】端口启动监听异常:{ex}"); } return isSuccess; })); }
public ProtocolWriter(Stream stream) : this(PipeWriter.Create(stream)) { }
/// <summary> /// 异步处理Socket SSL握手 /// </summary> /// <param name="socket"></param> private async void ProcessSocketAsync(Socket socket) { await Task.Run(() => { try { TSession session = new TSession() { Server = this, Socket = socket, Remote = socket.RemoteEndPoint.ToString(), Local = socket.LocalEndPoint.ToString() }; // Create a PipeReader over the network stream if (ServerOption.Security == SslProtocols.None) { session.Stream = new NetworkStream(session.Socket, true); session.Reader = PipeReader.Create(session.Stream); session.Writer = PipeWriter.Create(session.Stream); m_sessionManager.Add(session); OnConnected?.Invoke(session); ProcessReadAsync(session); } else { ServerOption.SslServerAuthenticationOptions.RemoteCertificateValidationCallback = SSLValidationCallback; var sslStream = new SslStream(new NetworkStream(session.Socket, true), false); var cancelTokenSource = new CancellationTokenSource(); cancelTokenSource.CancelAfter(5000); _ = sslStream.AuthenticateAsServerAsync(ServerOption.SslServerAuthenticationOptions, cancelTokenSource.Token).ContinueWith(t => { if (sslStream.IsAuthenticated) { session.Stream = sslStream; session.Reader = PipeReader.Create(session.Stream); session.Writer = PipeWriter.Create(session.Stream); m_sessionManager.Add(session); OnConnected?.Invoke(session); ProcessReadAsync(session); } else { if (t.IsCanceled) { HandleLog.WriteLine($"连接{session.Remote}证书验证超时,关闭连接"); } session.Close(); } }); } } catch (Exception ex) { HandleLog.WriteLine($"【{ServerOption.Port}】服务端口处理连接异常:{ex}"); socket?.Close(); } }); }
public DuplexPipeStreamAdapter(IDuplexPipe duplexPipe, StreamPipeReaderOptions readerOptions, StreamPipeWriterOptions writerOptions, Func <Stream, TStream> createStream) : base(duplexPipe.Input, duplexPipe.Output) { Stream = createStream(this); Input = PipeReader.Create(Stream, readerOptions); Output = PipeWriter.Create(Stream, writerOptions); }
private async Task <Stream> HandleInitialMessage(Stream stream, MessageBuilder messageBuilder) { var reader = PipeReader.Create(stream); var writer = PipeWriter.Create(stream); var streamToUse = stream; var messageReader = new MessageReader(); var initialMessage = await messageReader.ReadInitialMessage(reader, _token); if (initialMessage is SSLRequest) { if (_serverCertificate == null) { await writer.WriteAsync(messageBuilder.SSLResponse(false), _token); initialMessage = await messageReader.ReadInitialMessage(reader, _token); } else { await writer.WriteAsync(messageBuilder.SSLResponse(true), _token); var sslStream = new SslStream(stream, false, (sender, certificate, chain, errors) => true); await sslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions { ServerCertificate = _serverCertificate, ClientCertificateRequired = false }, _token); streamToUse = sslStream; var encryptedReader = PipeReader.Create(sslStream); initialMessage = await messageReader.ReadInitialMessage(encryptedReader, _token); } } switch (initialMessage) { case StartupMessage startupMessage: _clientOptions = startupMessage.ClientOptions; break; case SSLRequest: await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.ProtocolViolation, "SSLRequest received twice"), _token); break; case Cancel cancel: // TODO: Support Cancel message await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.FeatureNotSupported, "Cancel message support not implemented."), _token); break; default: await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.ProtocolViolation, "Invalid first message received"), _token); break; } return(streamToUse); }
/// <summary> /// 连接TCP服务 /// </summary> /// <returns></returns> public async Task <bool> ConnectAsync() { try { if (ClientOption == null) { throw new ArgumentException("ClientOption客户端配置尚未配置"); } Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { NoDelay = ClientOption.NoDelay }; //异步连接 await Socket.ConnectAsync(new IPEndPoint(IPAddress.Parse(ClientOption.Ip), ClientOption.Port)); RemoteEndPoint = Socket.RemoteEndPoint; LocalEndPoint = Socket.LocalEndPoint; //非SSL if (ClientOption.Security == SslProtocols.None) { //Socket转字节流对象 Stream = new NetworkStream(Socket, true); //字节流绑定到Pipe管道(高性能缓冲区) Reader = PipeReader.Create(Stream); //读取数据端 Writer = PipeWriter.Create(Stream); //发送数据端 IsConnected = true; LogHelper.Info($"连接服务器[{ClientOption.Ip}:{ClientOption.Port}]成功"); OnConnected?.Invoke(this); //开始异步接收数据 ProcessReadAsync(); return(true); } else { //SSL回调 ClientOption.SslClientAuthenticationOptions.RemoteCertificateValidationCallback = SSLValidationCallback; //加密传输字节流 var sslStream = new SslStream(new NetworkStream(Socket, true), false); var cancelTokenSource = new CancellationTokenSource(); //SSL认证超时时间为5s cancelTokenSource.CancelAfter(5000); return(await sslStream.AuthenticateAsClientAsync(ClientOption.SslClientAuthenticationOptions, cancelTokenSource.Token).ContinueWith(t => { if (sslStream.IsAuthenticated) { //验证成功 Stream = sslStream; //字节流绑定到Pipe管道(高性能缓冲区) Reader = PipeReader.Create(Stream); //读取数据端 Writer = PipeWriter.Create(Stream); //发送数据端 IsConnected = true; LogHelper.Info($"连接服务器[{ClientOption.Ip}:{ClientOption.Port}]成功"); OnConnected?.Invoke(this); //开始异步接收数据 ProcessReadAsync(); return true; } else { //验证失败 if (t.IsCanceled) { LogHelper.Error($"连接{RemoteEndPoint}证书验证超时,关闭连接"); } //关闭连接 Close(); return false; } })); } } catch (Exception ex) { //处理异常直接关闭客户端 if (IsConnected) { Close(); } IsConnected = false; LogHelper.Error($"客户端异常:{ex}"); return(false); } }
public async Task TestRoundtrip(string filename) { // Load byte[] decompressed = await File.ReadAllBytesAsync(filename); if (filename.EndsWith(".fse", StringComparison.OrdinalIgnoreCase)) { var ms = new MemoryStream(); await PipeHelper.DecompressAsync(PipeReader.Create(new MemoryStream(decompressed)), PipeWriter.Create(new NoDisposableStream(ms))); decompressed = ms.ToArray(); } // Compress var compressedStream = new MemoryStream(); await PipeHelper.CompressAsync(PipeReader.Create(new MemoryStream(decompressed)), PipeWriter.Create(new NoDisposableStream(compressedStream))); // Decompress compressedStream.Seek(0, SeekOrigin.Begin); var decompressedStream = new MemoryStream(); await PipeHelper.DecompressAsync(PipeReader.Create(compressedStream), PipeWriter.Create(new NoDisposableStream(decompressedStream))); // Compare decompressedStream.ToArray().AsSpan().SequenceCompareTo(decompressed); }
public async Task WriteAsync_DefaultWriteOptions_Flushes() { // Arrange var ms = new MemoryStream(); var httpContext = new DefaultHttpContext(); httpContext.Features.Set <IResponseBodyPipeFeature>(new TestResponseBodyPipeFeature(PipeWriter.Create(ms))); var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext); var writer = new HttpContextStreamWriter <HelloReply>(serverCallContext, (message) => message.ToByteArray()); // Act 1 await writer.WriteAsync(new HelloReply { Message = "Hello world 1" }); // Assert 1 Assert.AreEqual(20, ms.Length); // Act 2 await writer.WriteAsync(new HelloReply { Message = "Hello world 2" }); // Assert 2 Assert.AreEqual(40, ms.Length); ms.Seek(0, SeekOrigin.Begin); var pipeReader = PipeReader.Create(ms); var writtenMessage1 = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.AreEqual("Hello world 1", writtenMessage1 !.Message); var writtenMessage2 = await MessageHelpers.AssertReadStreamMessageAsync <HelloReply>(pipeReader); Assert.AreEqual("Hello world 2", writtenMessage2 !.Message); }
public override async ValueTask <byte[]> ResolveAsync(byte[] Query) { using var Socket = new Socket(SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = (int)Options.CurrentValue.Timeout.TotalMilliseconds, SendTimeout = (int)Options.CurrentValue.Timeout.TotalMilliseconds }; //await Socket.ConnectAsync(Options.CurrentValue.IPv4EndPoint); //var Prefix = new byte[2]; //BinaryPrimitives.WriteUInt16BigEndian(Prefix, (ushort)Query.Length); //await Socket.SendAsync(Prefix, SocketFlags.None); //await Socket.SendAsync(Query, SocketFlags.None); //await Socket.ReceiveAsync(Prefix, SocketFlags.None); //var Size = BinaryPrimitives.ReadUInt16BigEndian(Prefix); //var Buffer = new byte[Size]; //await Socket.ReliableReceiveAsync(Buffer); //return Buffer; await Socket.ConnectAsync(Options.CurrentValue.IPv4EndPoint); var Stream = new NetworkStream(Socket); var Reader = PipeReader.Create(Stream); var Writer = PipeWriter.Create(Stream); var CancellationTokenSource = new CancellationTokenSource(Options.CurrentValue.Timeout); var Prefix = new byte[2]; BinaryPrimitives.WriteUInt16BigEndian(Prefix, (ushort)Query.Length); await Writer.WriteAsync(Prefix, CancellationTokenSource.Token); await Writer.WriteAsync(Query, CancellationTokenSource.Token); await Writer.FlushAsync(CancellationTokenSource.Token); while (true) { var Result = await Reader.ReadAsync(CancellationTokenSource.Token); if (Result.IsCompleted) { var Size = BinaryPrimitives.ReadUInt16BigEndian(Result.Buffer.FirstSpan.Slice(0, 2)); return(Result.Buffer.FirstSpan.Slice(2, Size).ToArray()); } await Task.Delay(100, CancellationTokenSource.Token); } }
public async Task WriteAsync_WriteInProgress_Error() { // Arrange var tcs = new TaskCompletionSource <object?>(TaskCreationOptions.RunContinuationsAsynchronously); var httpContext = new DefaultHttpContext(); httpContext.Features.Set <IHttpResponseBodyFeature>(new TestResponseBodyFeature(PipeWriter.Create(new MemoryStream()), startAsyncTask: tcs.Task)); var serverCallContext = HttpContextServerCallContextHelper.CreateServerCallContext(httpContext); var writer = new HttpContextStreamWriter <HelloReply>(serverCallContext, MessageHelpers.ServiceMethod.ResponseMarshaller.ContextualSerializer); // Act _ = writer.WriteAsync(new HelloReply { Message = "Hello world 1" }); var ex = await ExceptionAssert.ThrowsAsync <InvalidOperationException>(() => { return(writer.WriteAsync(new HelloReply { Message = "Hello world 2" })); }); // Assert Assert.AreEqual("Can't write the message because the previous write is in progress.", ex.Message); }
internal StreamDuplexPipe(Stream stream) { this.stream = stream; this.Input = PipeReader.Create(stream, new StreamPipeReaderOptions(leaveOpen: true)); this.Output = PipeWriter.Create(stream, new StreamPipeWriterOptions(leaveOpen: true)); }
public async Task CanDoMultipleAsyncWritesToStream() { var pipe = new Pipe(new PipeOptions(readerScheduler: PipeScheduler.Inline)); PipeWriter writer = PipeWriter.Create(pipe.Writer.AsStream());
public async Task Run() { using var _ = _client; using var messageBuilder = new MessageBuilder(); Stream stream = _client.GetStream(); stream = await HandleInitialMessage(stream, messageBuilder); var reader = PipeReader.Create(stream); var writer = PipeWriter.Create(stream); if (_clientOptions == null) //TODO pfyasu maybe unused when cancel message will be implemented { return; } if (_clientOptions.TryGetValue("database", out string databaseName) == false) { await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.ConnectionFailure, "Failed to connect to database", "Missing database name in the connection string"), _token); return; } var database = await _databasesLandlord.TryGetOrCreateResourceStore(databaseName); if (database == null) { await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.ConnectionFailure, "Failed to connect to database", $"Database '{databaseName}' does not exist"), _token); return; } string username = null; try { username = _clientOptions["user"]; using var transaction = new PgTransaction(database, new MessageReader(), username); if (_serverCertificate != null) { // Authentication is required only when running in secured mode await writer.WriteAsync(messageBuilder.AuthenticationCleartextPassword(), _token); var authMessage = await transaction.MessageReader.GetUninitializedMessage(reader, _token); await authMessage.Init(transaction.MessageReader, reader, _token); await authMessage.Handle(transaction, messageBuilder, reader, writer, _token); } else { await writer.WriteAsync(messageBuilder.AuthenticationOk(), _token); } await writer.WriteAsync(messageBuilder.ParameterStatusMessages(PgConfig.ParameterStatusList), _token); await writer.WriteAsync(messageBuilder.BackendKeyData(_processId, _identifier), _token); await writer.WriteAsync(messageBuilder.ReadyForQuery(transaction.State), _token); while (_token.IsCancellationRequested == false) { var message = await transaction.MessageReader.GetUninitializedMessage(reader, _token); try { await message.Init(transaction.MessageReader, reader, _token); await message.Handle(transaction, messageBuilder, reader, writer, _token); } catch (PgErrorException e) { await message.HandleError(e, transaction, messageBuilder, writer, _token); } } } catch (PgFatalException e) { if (Logger.IsInfoEnabled) { Logger.Info($"{e.Message} (fatal pg error code {e.ErrorCode}). {GetSourceConnectionDetails(username)}", e); } await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, e.ErrorCode, e.Message, e.ToString()), _token); } catch (PgErrorException e) { if (Logger.IsInfoEnabled) { Logger.Info($"{e.Message} (pg error code {e.ErrorCode}). {GetSourceConnectionDetails(username)}", e); } // Shouldn't get to this point, PgErrorExceptions shouldn't be fatal await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Error, e.ErrorCode, e.Message, e.ToString()), _token); } catch (PgTerminateReceivedException) { // Terminate silently } catch (QueryParser.ParseException e) { if (Logger.IsInfoEnabled) { Logger.Info("Invalid RQL query", e); } try { await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Error, PgErrorCodes.InvalidSqlStatementName, e.ToString()), _token); } catch (Exception) { // ignored } } catch (Exception e) { if (Logger.IsInfoEnabled) { Logger.Info($"Unexpected internal pg error. {GetSourceConnectionDetails(username)}", e); } try { await writer.WriteAsync(messageBuilder.ErrorResponse( PgSeverity.Fatal, PgErrorCodes.InternalError, e.ToString()), _token); } catch (Exception) { // ignored } } }
private static PipeWriter CreateFakePipeWriter() { return(PipeWriter.Create(Stream.Null)); }