From d50cb023d70b3263f713ba790010d6d84a56d643 Mon Sep 17 00:00:00 2001 From: Adam Radocz Date: Sat, 6 Nov 2021 21:10:11 +0100 Subject: [PATCH 1/8] Update NuGet packages. --- .../ClientApplication/ClientApplication.csproj | 6 +++--- .../ServerApplication/ServerApplication.csproj | 4 ++-- .../Bedrock.Framework.Experimental.csproj | 8 ++++++-- src/Bedrock.Framework/Bedrock.Framework.csproj | 8 ++++++-- .../Bedrock.Framework.Benchmarks.csproj | 4 ++-- .../Bedrock.Framework.Tests.csproj | 16 +++++++++++----- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/samples/ClientApplication/ClientApplication.csproj b/samples/ClientApplication/ClientApplication.csproj index 07519626..3a7c1b5f 100644 --- a/samples/ClientApplication/ClientApplication.csproj +++ b/samples/ClientApplication/ClientApplication.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net6.0 @@ -14,8 +14,8 @@ - - + + diff --git a/samples/ServerApplication/ServerApplication.csproj b/samples/ServerApplication/ServerApplication.csproj index bfb90c4d..06d83219 100644 --- a/samples/ServerApplication/ServerApplication.csproj +++ b/samples/ServerApplication/ServerApplication.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net6.0 @@ -10,7 +10,7 @@ - + diff --git a/src/Bedrock.Framework.Experimental/Bedrock.Framework.Experimental.csproj b/src/Bedrock.Framework.Experimental/Bedrock.Framework.Experimental.csproj index 7bba7647..9f600cdd 100644 --- a/src/Bedrock.Framework.Experimental/Bedrock.Framework.Experimental.csproj +++ b/src/Bedrock.Framework.Experimental/Bedrock.Framework.Experimental.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net6.0 true Experimental protocols and transports for Bedrock.Framework. David Fowler @@ -18,6 +18,10 @@ - + + + + + diff --git a/src/Bedrock.Framework/Bedrock.Framework.csproj b/src/Bedrock.Framework/Bedrock.Framework.csproj index 861ce1e6..0b402352 100644 --- a/src/Bedrock.Framework/Bedrock.Framework.csproj +++ b/src/Bedrock.Framework/Bedrock.Framework.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net6.0 High performance, low level networking APIs for building custom severs and clients. David Fowler true @@ -12,6 +12,10 @@ - + + + + + diff --git a/tests/Bedrock.Framework.Benchmarks/Bedrock.Framework.Benchmarks.csproj b/tests/Bedrock.Framework.Benchmarks/Bedrock.Framework.Benchmarks.csproj index 3782ba29..5fb3d2e1 100644 --- a/tests/Bedrock.Framework.Benchmarks/Bedrock.Framework.Benchmarks.csproj +++ b/tests/Bedrock.Framework.Benchmarks/Bedrock.Framework.Benchmarks.csproj @@ -2,11 +2,11 @@ Exe - netcoreapp3.1 + net6.0 - + diff --git a/tests/Bedrock.Framework.Tests/Bedrock.Framework.Tests.csproj b/tests/Bedrock.Framework.Tests/Bedrock.Framework.Tests.csproj index e678b9a9..1b94f27a 100644 --- a/tests/Bedrock.Framework.Tests/Bedrock.Framework.Tests.csproj +++ b/tests/Bedrock.Framework.Tests/Bedrock.Framework.Tests.csproj @@ -1,16 +1,22 @@  - netcoreapp3.1 + net6.0 false - - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From 8f38cec6df062725b8770885fba07b14e85ba5ce Mon Sep 17 00:00:00 2001 From: Adam Radocz Date: Sat, 6 Nov 2021 21:49:58 +0100 Subject: [PATCH 2/8] Fix to build in .NET 6.0 framework. --- samples/ServerApplication/MqttApplication.cs | 7 +++---- .../Protocols/Http1RequestMessageReader.cs | 2 +- .../Protocols/Http1ResponseMessageReader.cs | 2 +- tests/Bedrock.Framework.Tests/ProtocolTests.cs | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/samples/ServerApplication/MqttApplication.cs b/samples/ServerApplication/MqttApplication.cs index 3b964821..3b74d663 100644 --- a/samples/ServerApplication/MqttApplication.cs +++ b/samples/ServerApplication/MqttApplication.cs @@ -19,7 +19,7 @@ private async Task OnClientConnectedAsync(IMqttChannelAdapter adapter) { while (true) { - var packet = await adapter.ReceivePacketAsync(Timeout.InfiniteTimeSpan, default); + var packet = await adapter.ReceivePacketAsync(default); switch (packet) { @@ -29,8 +29,7 @@ await adapter.SendPacketAsync(new MqttConnAckPacket ReturnCode = MqttConnectReturnCode.ConnectionAccepted, ReasonCode = MqttConnectReasonCode.Success, IsSessionPresent = false - }, Timeout.InfiniteTimeSpan, - default); + }, default); break; case MqttDisconnectPacket disconnectPacket: break; @@ -48,7 +47,7 @@ await adapter.SendPacketAsync(new MqttConnAckPacket }; ack.ReasonCodes.Add(MqttSubscribeReasonCode.GrantedQoS0); - await adapter.SendPacketAsync(ack, Timeout.InfiniteTimeSpan, default); + await adapter.SendPacketAsync(ack, default); break; default: break; diff --git a/src/Bedrock.Framework.Experimental/Protocols/Http1RequestMessageReader.cs b/src/Bedrock.Framework.Experimental/Protocols/Http1RequestMessageReader.cs index 1718d212..9245a139 100644 --- a/src/Bedrock.Framework.Experimental/Protocols/Http1RequestMessageReader.cs +++ b/src/Bedrock.Framework.Experimental/Protocols/Http1RequestMessageReader.cs @@ -54,7 +54,7 @@ public bool TryParseMessage(in ReadOnlySequence input, ref SequencePositio goto case State.Headers; case State.Headers: - while (sequenceReader.TryReadTo(out var headerLine, NewLine)) + while (sequenceReader.TryReadTo(out ReadOnlySequence headerLine, NewLine)) { if (headerLine.Length == 0) { diff --git a/src/Bedrock.Framework.Experimental/Protocols/Http1ResponseMessageReader.cs b/src/Bedrock.Framework.Experimental/Protocols/Http1ResponseMessageReader.cs index 02cc8f0d..d0f44633 100644 --- a/src/Bedrock.Framework.Experimental/Protocols/Http1ResponseMessageReader.cs +++ b/src/Bedrock.Framework.Experimental/Protocols/Http1ResponseMessageReader.cs @@ -59,7 +59,7 @@ public bool TryParseMessage(in ReadOnlySequence input, ref SequencePositio goto case State.Headers; case State.Headers: - while (sequenceReader.TryReadTo(out var headerLine, NewLine)) + while (sequenceReader.TryReadTo(out ReadOnlySequence headerLine, NewLine)) { if (headerLine.Length == 0) { diff --git a/tests/Bedrock.Framework.Tests/ProtocolTests.cs b/tests/Bedrock.Framework.Tests/ProtocolTests.cs index b748d83f..5446b5cb 100644 --- a/tests/Bedrock.Framework.Tests/ProtocolTests.cs +++ b/tests/Bedrock.Framework.Tests/ProtocolTests.cs @@ -274,7 +274,7 @@ public async Task ReadAfterCancellationTokenFiresWorks() var cts = new CancellationTokenSource(); cts.Cancel(); - await Assert.ThrowsAsync(async () => await reader.ReadAsync(protocol, cts.Token)); + await Assert.ThrowsAsync(async () => await reader.ReadAsync(protocol, cts.Token)); await connection.Application.Output.WriteAsync(data); From 3ce5dd71db3617a68c5b024dbfb8bb669f7f7fa3 Mon Sep 17 00:00:00 2001 From: Adam Radocz Date: Mon, 8 Nov 2021 20:43:39 +0100 Subject: [PATCH 3/8] Update NuGet packages. --- samples/ClientApplication/ClientApplication.csproj | 2 +- .../Bedrock.Framework.Experimental.csproj | 2 +- src/Bedrock.Framework/Bedrock.Framework.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/ClientApplication/ClientApplication.csproj b/samples/ClientApplication/ClientApplication.csproj index 3a7c1b5f..44a199db 100644 --- a/samples/ClientApplication/ClientApplication.csproj +++ b/samples/ClientApplication/ClientApplication.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/Bedrock.Framework.Experimental/Bedrock.Framework.Experimental.csproj b/src/Bedrock.Framework.Experimental/Bedrock.Framework.Experimental.csproj index 9f600cdd..64cda6ec 100644 --- a/src/Bedrock.Framework.Experimental/Bedrock.Framework.Experimental.csproj +++ b/src/Bedrock.Framework.Experimental/Bedrock.Framework.Experimental.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/Bedrock.Framework/Bedrock.Framework.csproj b/src/Bedrock.Framework/Bedrock.Framework.csproj index 0b402352..9d1f2358 100644 --- a/src/Bedrock.Framework/Bedrock.Framework.csproj +++ b/src/Bedrock.Framework/Bedrock.Framework.csproj @@ -12,7 +12,7 @@ - + From 6a19fe26dd2a38744ada93cfff7d09627cc2d8dd Mon Sep 17 00:00:00 2001 From: Adam Radocz Date: Fri, 10 Dec 2021 13:25:54 +0100 Subject: [PATCH 4/8] Dispose LoggerFactory Dispose LoggerFactory instances in the Client Sample app. --- samples/ClientApplication/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/ClientApplication/Program.cs b/samples/ClientApplication/Program.cs index c84f0f68..3e867461 100644 --- a/samples/ClientApplication/Program.cs +++ b/samples/ClientApplication/Program.cs @@ -97,7 +97,7 @@ static async Task Main(string[] args) private static async Task RabbitMQProtocol(IServiceProvider serviceProvider) { - var loggerFactory = LoggerFactory.Create(builder => + using var loggerFactory = LoggerFactory.Create(builder => { builder.SetMinimumLevel(LogLevel.Error); builder.AddConsole(); @@ -139,7 +139,7 @@ await rabbitMqClientProtocol.SendAsync(new ConnectionOpen(new ReadOnlyMemory + using var loggerFactory = LoggerFactory.Create(builder => { builder.SetMinimumLevel(LogLevel.Error); builder.AddConsole(); @@ -320,7 +320,7 @@ private static async Task InMemoryEchoTransport(IServiceProvider serviceProvider private static async Task CustomProtocol() { - var loggerFactory = LoggerFactory.Create(builder => + using var loggerFactory = LoggerFactory.Create(builder => { builder.SetMinimumLevel(LogLevel.Debug); builder.AddConsole(); From f58904207eb3ce9dae7c0e06e57758dea4f8d109 Mon Sep 17 00:00:00 2001 From: Adam Radocz Date: Fri, 10 Dec 2021 21:59:57 +0100 Subject: [PATCH 5/8] Fix connection message The "Connected to LocalEndPoint" message changed to "Connected to RemoteEndPoint", since the client is connecting to the server. --- samples/ClientApplication/Program.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/samples/ClientApplication/Program.cs b/samples/ClientApplication/Program.cs index c84f0f68..cb973029 100644 --- a/samples/ClientApplication/Program.cs +++ b/samples/ClientApplication/Program.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System; using System.IO; using System.IO.Pipelines; using System.Net; @@ -171,7 +170,7 @@ private static async Task EchoServer(IServiceProvider serviceProvider) .Build(); var connection = await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 5000)); - Console.WriteLine($"Connected to {connection.LocalEndPoint}"); + Console.WriteLine($"Connected to {connection.RemoteEndPoint}"); Console.WriteLine("Echo server running, type into the console"); var reads = Console.OpenStandardInput().CopyToAsync(connection.Transport.Output); @@ -255,7 +254,6 @@ private static async Task SignalR() } } - private static async Task EchoServerWithTls(ServiceProvider serviceProvider) { var client = new ClientBuilder(serviceProvider) @@ -276,7 +274,7 @@ private static async Task EchoServerWithTls(ServiceProvider serviceProvider) .Build(); var connection = await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 5004)); - Console.WriteLine($"Connected to {connection.LocalEndPoint}"); + Console.WriteLine($"Connected to {connection.RemoteEndPoint}"); Console.WriteLine("Echo server running, type into the console"); var reads = Console.OpenStandardInput().CopyToAsync(connection.Transport.Output); @@ -306,7 +304,7 @@ private static async Task InMemoryEchoTransport(IServiceProvider serviceProvider Console.WriteLine("Started Server"); var connection = await client.ConnectAsync(endpoint: null); - Console.WriteLine($"Connected to {connection.LocalEndPoint}"); + Console.WriteLine($"Connected to {connection.RemoteEndPoint}"); Console.WriteLine("Echo server running, type into the console"); var reads = Console.OpenStandardInput().CopyToAsync(connection.Transport.Output); @@ -332,7 +330,7 @@ private static async Task CustomProtocol() .Build(); await using var connection = await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 5005)); - Console.WriteLine($"Connected to {connection.LocalEndPoint}"); + Console.WriteLine($"Connected to {connection.RemoteEndPoint}"); var protocol = new LengthPrefixedProtocol(); var reader = connection.CreateReader(); From 3847eef25a935f32ddd91aec986ec4effa76368d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Rad=C3=B3cz?= Date: Sat, 11 Dec 2021 09:07:05 +0100 Subject: [PATCH 6/8] Add CompleteAsync and CancelPending to the Protocols. --- .../Protocols/ProtocolReader.cs | 21 +++++++++++++++++++ .../Protocols/ProtocolWriter.cs | 20 ++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/Bedrock.Framework/Protocols/ProtocolReader.cs b/src/Bedrock.Framework/Protocols/ProtocolReader.cs index f85c447a..02ed1e41 100644 --- a/src/Bedrock.Framework/Protocols/ProtocolReader.cs +++ b/src/Bedrock.Framework/Protocols/ProtocolReader.cs @@ -241,6 +241,27 @@ public void Advance() _hasMessage = false; } + public void CancelPendingRead() + { + if (_disposed) + { + throw new ObjectDisposedException(GetType().Name); + } + + _reader.CancelPendingRead(); + _isCanceled = true; + } + + public async ValueTask CompleteAsync() + { + if (_disposed) + { + throw new ObjectDisposedException(GetType().Name); + } + + await _reader.CompleteAsync(); + } + public ValueTask DisposeAsync() { _disposed = true; diff --git a/src/Bedrock.Framework/Protocols/ProtocolWriter.cs b/src/Bedrock.Framework/Protocols/ProtocolWriter.cs index ad8a997e..0fcbd3f6 100644 --- a/src/Bedrock.Framework/Protocols/ProtocolWriter.cs +++ b/src/Bedrock.Framework/Protocols/ProtocolWriter.cs @@ -95,6 +95,26 @@ public async ValueTask WriteManyAsync(IMessageWriter Date: Sat, 11 Dec 2021 18:36:09 +0100 Subject: [PATCH 7/8] Update the Custom protocol to show how to disconnect the client from the server. --- samples/ClientApplication/Program.cs | 42 ++++++++++++------- samples/ServerApplication/MyCustomProtocol.cs | 4 ++ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/samples/ClientApplication/Program.cs b/samples/ClientApplication/Program.cs index c84f0f68..2278b39f 100644 --- a/samples/ClientApplication/Program.cs +++ b/samples/ClientApplication/Program.cs @@ -32,20 +32,21 @@ static async Task Main(string[] args) }) .BuildServiceProvider(); - Console.WriteLine("Samples: "); - Console.WriteLine("1. Echo Server"); - Console.WriteLine("2. HttpClient"); - Console.WriteLine("3. SignalR"); - Console.WriteLine("4. Echo Server With TLS enabled"); - Console.WriteLine("5. In Memory Transport Echo Server and client"); - Console.WriteLine("6. Length prefixed custom binary protocol"); - Console.WriteLine("7. Talk to local docker dameon"); - Console.WriteLine("8. Memcached protocol"); - Console.WriteLine("9. RebbitMQ protocol"); - while (true) { + Console.WriteLine("Samples: "); + Console.WriteLine("1. Echo Server"); + Console.WriteLine("2. HttpClient"); + Console.WriteLine("3. SignalR"); + Console.WriteLine("4. Echo Server With TLS enabled"); + Console.WriteLine("5. In Memory Transport Echo Server and client"); + Console.WriteLine("6. Length prefixed custom binary protocol"); + Console.WriteLine("7. Talk to local docker dameon"); + Console.WriteLine("8. Memcached protocol"); + Console.WriteLine("9. RebbitMQ protocol"); + var keyInfo = Console.ReadKey(); + Console.Clear(); if (keyInfo.Key == ConsoleKey.D1) { @@ -92,6 +93,8 @@ static async Task Main(string[] args) Console.WriteLine("RabbitMQ test"); await RabbitMQProtocol(serviceProvider); } + + Console.Clear(); } } @@ -333,24 +336,35 @@ private static async Task CustomProtocol() await using var connection = await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 5005)); Console.WriteLine($"Connected to {connection.LocalEndPoint}"); + Console.WriteLine("Enter 'c' to close the connection."); var protocol = new LengthPrefixedProtocol(); - var reader = connection.CreateReader(); - var writer = connection.CreateWriter(); + await using var reader = connection.CreateReader(); + await using var writer = connection.CreateWriter(); while (true) { var line = Console.ReadLine(); + if (line.Equals("c")) + { + await reader.CompleteAsync(); + await writer.CompleteAsync(); + break; + } + await writer.WriteAsync(protocol, new Message(Encoding.UTF8.GetBytes(line))); var result = await reader.ReadAsync(protocol); - if (result.IsCompleted) + if (result.IsCompleted || result.IsCanceled) { break; } reader.Advance(); } + + // If the DisposeAsync not called explicitly, the connection won't close. + await connection.DisposeAsync(); } private static async Task DockerDaemon(IServiceProvider serviceProvider) diff --git a/samples/ServerApplication/MyCustomProtocol.cs b/samples/ServerApplication/MyCustomProtocol.cs index 9c503f4e..2bb688c0 100644 --- a/samples/ServerApplication/MyCustomProtocol.cs +++ b/samples/ServerApplication/MyCustomProtocol.cs @@ -17,6 +17,8 @@ public MyCustomProtocol(ILogger logger) public override async Task OnConnectedAsync(ConnectionContext connection) { + _logger.LogInformation("{ConnectionId} connected.", connection.ConnectionId); + // Use a length prefixed protocol var protocol = new LengthPrefixedProtocol(); var reader = connection.CreateReader(); @@ -43,6 +45,8 @@ public override async Task OnConnectedAsync(ConnectionContext connection) reader.Advance(); } } + + _logger.LogInformation("{ConnectionId} disconnected.", connection.ConnectionId); } } } \ No newline at end of file From 9746298dddca0985d56735be7d951185bd95aa7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Rad=C3=B3cz?= Date: Tue, 14 Dec 2021 18:48:39 +0100 Subject: [PATCH 8/8] Add Connection Abort --- samples/ClientApplication/Program.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/ClientApplication/Program.cs b/samples/ClientApplication/Program.cs index 2278b39f..9da1c11b 100644 --- a/samples/ClientApplication/Program.cs +++ b/samples/ClientApplication/Program.cs @@ -363,6 +363,8 @@ private static async Task CustomProtocol() reader.Advance(); } + connection.Abort(); + // If the DisposeAsync not called explicitly, the connection won't close. await connection.DisposeAsync(); }