diff --git a/BedrockFramework.sln b/BedrockFramework.sln index 94f5d1cd..9cef0a88 100644 --- a/BedrockFramework.sln +++ b/BedrockFramework.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29112.163 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32112.339 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientApplication", "samples\ClientApplication\ClientApplication.csproj", "{44A257ED-D3A7-4170-BE67-4392F2A6FE18}" EndProject @@ -26,6 +26,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bedrock.Framework.Experimen EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bedrock.Framework.Benchmarks", "tests\Bedrock.Framework.Benchmarks\Bedrock.Framework.Benchmarks.csproj", "{E4532856-96A9-47F1-9718-9FD596362493}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UdpServerApplication", "UdpServerApplication\UdpServerApplication.csproj", "{130151E8-8A8E-4B66-A667-46BE2AEE0193}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -56,6 +58,10 @@ Global {E4532856-96A9-47F1-9718-9FD596362493}.Debug|Any CPU.Build.0 = Debug|Any CPU {E4532856-96A9-47F1-9718-9FD596362493}.Release|Any CPU.ActiveCfg = Release|Any CPU {E4532856-96A9-47F1-9718-9FD596362493}.Release|Any CPU.Build.0 = Release|Any CPU + {130151E8-8A8E-4B66-A667-46BE2AEE0193}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {130151E8-8A8E-4B66-A667-46BE2AEE0193}.Debug|Any CPU.Build.0 = Debug|Any CPU + {130151E8-8A8E-4B66-A667-46BE2AEE0193}.Release|Any CPU.ActiveCfg = Release|Any CPU + {130151E8-8A8E-4B66-A667-46BE2AEE0193}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -67,6 +73,7 @@ Global {37FED75D-A02F-43AF-B888-F331634C3FA7} = {1F47B42E-790F-48AA-8BFB-AD1986D05A67} {B77439AE-01C0-4877-AF91-180D521F6E55} = {BE56BD3F-A489-42F7-A3E3-93AE5A0A54E2} {E4532856-96A9-47F1-9718-9FD596362493} = {1F47B42E-790F-48AA-8BFB-AD1986D05A67} + {130151E8-8A8E-4B66-A667-46BE2AEE0193} = {B0C0F79A-2A88-4ADB-9E15-62C1EA26A96D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {05222274-E7CB-4ABA-9ADF-4A3DBB1D0417} diff --git a/UdpServerApplication/Program.cs b/UdpServerApplication/Program.cs new file mode 100644 index 00000000..f2b6f26e --- /dev/null +++ b/UdpServerApplication/Program.cs @@ -0,0 +1,39 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace UdpServerApplication +{ + internal class Program + { + private const int listenPort = 5007; + + static void Main(string[] args) + { + UdpClient listener = new UdpClient(listenPort); + IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, listenPort); + + Console.WriteLine($"UDP Server. Waiting for broadcast on {listenPort}"); + + try + { + while (true) + { + byte[] bytes = listener.Receive(ref endPoint); + + Console.WriteLine($"Received broadcast from {endPoint} :"); + Console.WriteLine($" {Encoding.ASCII.GetString(bytes, 0, bytes.Length)}"); + } + } + catch (SocketException e) + { + Console.WriteLine(e); + } + finally + { + listener.Close(); + } + } + } +} diff --git a/UdpServerApplication/UdpServerApplication.csproj b/UdpServerApplication/UdpServerApplication.csproj new file mode 100644 index 00000000..c73e0d16 --- /dev/null +++ b/UdpServerApplication/UdpServerApplication.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp3.1 + + + diff --git a/samples/ClientApplication/Program.cs b/samples/ClientApplication/Program.cs index c84f0f68..db43d73e 100644 --- a/samples/ClientApplication/Program.cs +++ b/samples/ClientApplication/Program.cs @@ -18,6 +18,7 @@ using Microsoft.Extensions.Logging; using Protocols; using Bedrock.Framework.Experimental.Protocols.RabbitMQ.Methods; +using System.Net.Sockets; namespace ClientApplication { @@ -42,6 +43,7 @@ static async Task Main(string[] args) Console.WriteLine("7. Talk to local docker dameon"); Console.WriteLine("8. Memcached protocol"); Console.WriteLine("9. RebbitMQ protocol"); + Console.WriteLine("U. UDP Transport"); while (true) { @@ -92,6 +94,11 @@ static async Task Main(string[] args) Console.WriteLine("RabbitMQ test"); await RabbitMQProtocol(serviceProvider); } + else if (keyInfo.Key == ConsoleKey.U) + { + Console.WriteLine("UDP transport"); + await UdpTransport(); + } } } @@ -392,6 +399,44 @@ private static async Task DockerDaemon(IServiceProvider serviceProvider) Console.WriteLine(); } } + + private static async Task UdpTransport() + { + using var loggerFactory = LoggerFactory.Create(builder => + { + builder.SetMinimumLevel(LogLevel.Debug); + builder.AddConsole(); + }); + + var client = new ClientBuilder() + .UseSockets(SocketType.Dgram, ProtocolType.Udp) + .UseConnectionLogging(loggerFactory: loggerFactory) + .Build(); + + await using var connection = await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 5007)); + Console.WriteLine($"Connected to {connection.RemoteEndPoint}"); + Console.WriteLine("Enter 'c' to close the connection."); + + var protocol = new LengthPrefixedProtocol(); + await using var reader = connection.CreateReader(); + await using var writer = connection.CreateWriter(); + + while (true) + { + Console.WriteLine("Enter the text: "); + var line = Console.ReadLine(); + if (line.Equals("c")) + { + break; + } + + await writer.WriteAsync(protocol, new Message(Encoding.UTF8.GetBytes(line))); + + reader.Advance(); + } + + connection.Abort(); + } } // Property bag needed on ConnectAsync and BindAsync diff --git a/src/Bedrock.Framework/Transports/Sockets/ServerBuilderExtensions.cs b/src/Bedrock.Framework/Transports/Sockets/ServerBuilderExtensions.cs index 814aec9a..1d9d56f8 100644 --- a/src/Bedrock.Framework/Transports/Sockets/ServerBuilderExtensions.cs +++ b/src/Bedrock.Framework/Transports/Sockets/ServerBuilderExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; @@ -16,9 +17,9 @@ public static ServerBuilder UseSockets(this ServerBuilder serverBuilder, Action< return serverBuilder; } - public static ClientBuilder UseSockets(this ClientBuilder clientBuilder) + public static ClientBuilder UseSockets(this ClientBuilder clientBuilder, SocketType socketType = SocketType.Stream, ProtocolType protocolType = ProtocolType.Tcp) { - return clientBuilder.UseConnectionFactory(new SocketConnectionFactory()); + return clientBuilder.UseConnectionFactory(new SocketConnectionFactory(socketType, protocolType)); } } } \ No newline at end of file diff --git a/src/Bedrock.Framework/Transports/Sockets/SocketConnection.cs b/src/Bedrock.Framework/Transports/Sockets/SocketConnection.cs index 00ec6ca6..6d7b4368 100644 --- a/src/Bedrock.Framework/Transports/Sockets/SocketConnection.cs +++ b/src/Bedrock.Framework/Transports/Sockets/SocketConnection.cs @@ -21,9 +21,9 @@ internal class SocketConnection : ConnectionContext, IConnectionInherentKeepAliv private readonly SocketSender _sender; private readonly SocketReceiver _receiver; - public SocketConnection(EndPoint endPoint) + public SocketConnection(EndPoint endPoint, SocketType socketType, ProtocolType protocolType) { - _socket = new Socket(endPoint.AddressFamily, SocketType.Stream, DetermineProtocolType(endPoint)); + _socket = new Socket(endPoint.AddressFamily, socketType, protocolType); _endPoint = endPoint; _sender = new SocketSender(_socket, PipeScheduler.ThreadPool); @@ -250,16 +250,5 @@ private async Task ProcessSends() } } } - - private static ProtocolType DetermineProtocolType(EndPoint endPoint) - { - switch (endPoint) - { - case UnixDomainSocketEndPoint _: - return ProtocolType.Unspecified; - default: - return ProtocolType.Tcp; - } - } } } diff --git a/src/Bedrock.Framework/Transports/Sockets/SocketConnectionFactory.cs b/src/Bedrock.Framework/Transports/Sockets/SocketConnectionFactory.cs index 3a484029..710a2a72 100644 --- a/src/Bedrock.Framework/Transports/Sockets/SocketConnectionFactory.cs +++ b/src/Bedrock.Framework/Transports/Sockets/SocketConnectionFactory.cs @@ -11,9 +11,18 @@ namespace Bedrock.Framework { public class SocketConnectionFactory : IConnectionFactory { + private readonly SocketType _socketType; + private readonly ProtocolType _protocolType; + + public SocketConnectionFactory(SocketType socketType, ProtocolType protocolType) + { + _socketType = socketType; + _protocolType = protocolType; + } + public ValueTask ConnectAsync(EndPoint endpoint, CancellationToken cancellationToken = default) { - return new SocketConnection(endpoint).StartAsync(); + return new SocketConnection(endpoint, _socketType, _protocolType).StartAsync(); } } }