diff --git a/Source/MQTTnet.AspnetCore/Client/Tcp/TcpConnection.cs b/Source/MQTTnet.AspnetCore/Client/Tcp/TcpConnection.cs index 37913fe4..4cc16683 100644 --- a/Source/MQTTnet.AspnetCore/Client/Tcp/TcpConnection.cs +++ b/Source/MQTTnet.AspnetCore/Client/Tcp/TcpConnection.cs @@ -40,8 +40,11 @@ namespace MQTTnet.AspNetCore.Client.Tcp _sender = new SocketSender(_socket, PipeScheduler.ThreadPool); _receiver = new SocketReceiver(_socket, PipeScheduler.ThreadPool); } - +#if NETCOREAPP3_1 + public override ValueTask DisposeAsync() +#else public Task DisposeAsync() +#endif { IsConnected = false; @@ -50,8 +53,15 @@ namespace MQTTnet.AspNetCore.Client.Tcp _socket?.Dispose(); +#if NETCOREAPP3_1 + + return base.DisposeAsync(); + } +#else + return Task.CompletedTask; } +#endif public async Task StartAsync() { diff --git a/Source/MQTTnet.AspnetCore/ApplicationBuilderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ApplicationBuilderExtensions.cs similarity index 75% rename from Source/MQTTnet.AspnetCore/ApplicationBuilderExtensions.cs rename to Source/MQTTnet.AspnetCore/Extensions/ApplicationBuilderExtensions.cs index 94fc8e41..759b064d 100644 --- a/Source/MQTTnet.AspnetCore/ApplicationBuilderExtensions.cs +++ b/Source/MQTTnet.AspnetCore/Extensions/ApplicationBuilderExtensions.cs @@ -1,14 +1,13 @@ using System; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; -using System.Linq; using MQTTnet.Server; -using System.Collections.Generic; namespace MQTTnet.AspNetCore { public static class ApplicationBuilderExtensions { + [Obsolete("This class is obsolete and will be removed in a future version. The recommended alternative is to use MapMqtt inside Microsoft.AspNetCore.Builder.UseEndpoints(...).")] public static IApplicationBuilder UseMqttEndpoint(this IApplicationBuilder app, string path = "/mqtt") { app.UseWebSockets(); @@ -24,7 +23,7 @@ namespace MQTTnet.AspNetCore if (context.Request.Headers.TryGetValue("Sec-WebSocket-Protocol", out var requestedSubProtocolValues)) { - subProtocol = SelectSubProtocol(requestedSubProtocolValues); + subProtocol = MqttSubProtocolSelector.SelectSubProtocol(requestedSubProtocolValues); } var adapter = app.ApplicationServices.GetRequiredService(); @@ -37,14 +36,6 @@ namespace MQTTnet.AspNetCore return app; } - public static string SelectSubProtocol(IList requestedSubProtocolValues) - { - // Order the protocols to also match "mqtt", "mqttv-3.1", "mqttv-3.11" etc. - return requestedSubProtocolValues - .OrderByDescending(p => p.Length) - .FirstOrDefault(p => p.ToLower().StartsWith("mqtt")); - } - public static IApplicationBuilder UseMqttServer(this IApplicationBuilder app, Action configure) { var server = app.ApplicationServices.GetRequiredService(); diff --git a/Source/MQTTnet.AspnetCore/ConnectionBuilderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ConnectionBuilderExtensions.cs similarity index 100% rename from Source/MQTTnet.AspnetCore/ConnectionBuilderExtensions.cs rename to Source/MQTTnet.AspnetCore/Extensions/ConnectionBuilderExtensions.cs diff --git a/Source/MQTTnet.AspnetCore/Extensions/ConnectionRouteBuilderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ConnectionRouteBuilderExtensions.cs new file mode 100644 index 00000000..d6749884 --- /dev/null +++ b/Source/MQTTnet.AspnetCore/Extensions/ConnectionRouteBuilderExtensions.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Connections; +using System; + +namespace MQTTnet.AspNetCore +{ + public static class ConnectionRouteBuilderExtensions + { +#if NETCOREAPP3_1 + [Obsolete("This class is obsolete and will be removed in a future version. The recommended alternative is to use MapMqtt inside Microsoft.AspNetCore.Builder.UseEndpoints(...).")] +#endif + public static void MapMqtt(this ConnectionsRouteBuilder connection, PathString path) + { + connection.MapConnectionHandler(path, options => + { + options.WebSockets.SubProtocolSelector = MqttSubProtocolSelector.SelectSubProtocol; + }); + } + } +} diff --git a/Source/MQTTnet.AspnetCore/Extensions/EndpointRouterExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/EndpointRouterExtensions.cs new file mode 100644 index 00000000..d2a28054 --- /dev/null +++ b/Source/MQTTnet.AspnetCore/Extensions/EndpointRouterExtensions.cs @@ -0,0 +1,21 @@ + +#if NETCOREAPP3_1 + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Routing; + +namespace MQTTnet.AspNetCore +{ + public static class EndpointRouterExtensions + { + public static void MapMqtt(this IEndpointRouteBuilder endpoints, string pattern) + { + endpoints.MapConnectionHandler(pattern, options => + { + options.WebSockets.SubProtocolSelector = MqttSubProtocolSelector.SelectSubProtocol; + }); + } + } +} + +#endif diff --git a/Source/MQTTnet.AspnetCore/ReaderExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs similarity index 100% rename from Source/MQTTnet.AspnetCore/ReaderExtensions.cs rename to Source/MQTTnet.AspnetCore/Extensions/ReaderExtensions.cs diff --git a/Source/MQTTnet.AspnetCore/ServiceCollectionExtensions.cs b/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs similarity index 100% rename from Source/MQTTnet.AspnetCore/ServiceCollectionExtensions.cs rename to Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs index d9d9fdb8..8606142f 100644 --- a/Source/MQTTnet.AspnetCore/ServiceCollectionExtensions.cs +++ b/Source/MQTTnet.AspnetCore/Extensions/ServiceCollectionExtensions.cs @@ -1,10 +1,10 @@ using System; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using MQTTnet.Adapter; using MQTTnet.Diagnostics; using MQTTnet.Server; using MQTTnet.Implementations; +using Microsoft.Extensions.DependencyInjection; namespace MQTTnet.AspNetCore { diff --git a/Source/MQTTnet.AspnetCore/MqttHostedServer.cs b/Source/MQTTnet.AspnetCore/MqttHostedServer.cs index 4b6b436b..323c4956 100644 --- a/Source/MQTTnet.AspnetCore/MqttHostedServer.cs +++ b/Source/MQTTnet.AspnetCore/MqttHostedServer.cs @@ -21,7 +21,8 @@ namespace MQTTnet.AspNetCore public Task StartAsync(CancellationToken cancellationToken) { - return StartAsync(_options); + _ = StartAsync(_options); + return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) diff --git a/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs b/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs new file mode 100644 index 00000000..d400ab3d --- /dev/null +++ b/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.Linq; + +namespace MQTTnet.AspNetCore +{ + public static class MqttSubProtocolSelector + { + public static string SelectSubProtocol(IList requestedSubProtocolValues) + { + // Order the protocols to also match "mqtt", "mqttv-3.1", "mqttv-3.11" etc. + return requestedSubProtocolValues + .OrderByDescending(p => p.Length) + .FirstOrDefault(p => p.ToLower().StartsWith("mqtt")); + } + } +} diff --git a/Tests/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj b/Tests/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj index b34c5a3a..5d11fac9 100644 --- a/Tests/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj +++ b/Tests/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj @@ -16,7 +16,6 @@ - \ No newline at end of file diff --git a/Tests/MQTTnet.Benchmarks/MessageProcessingMqttConnectionContextBenchmark.cs b/Tests/MQTTnet.Benchmarks/MessageProcessingMqttConnectionContextBenchmark.cs index 7bd085c2..87ec1348 100644 --- a/Tests/MQTTnet.Benchmarks/MessageProcessingMqttConnectionContextBenchmark.cs +++ b/Tests/MQTTnet.Benchmarks/MessageProcessingMqttConnectionContextBenchmark.cs @@ -26,11 +26,8 @@ namespace MQTTnet.Benchmarks _host = WebHost.CreateDefaultBuilder() .UseKestrel(o => o.ListenAnyIP(1883, l => l.UseMqtt())) .ConfigureServices(services => { - var mqttServerOptions = new MqttServerOptionsBuilder() - .WithoutDefaultEndpoint() - .Build(); services - .AddHostedMqttServer(mqttServerOptions) + .AddHostedMqttServer(mqttServerOptions => mqttServerOptions.WithoutDefaultEndpoint()) .AddMqttConnectionHandler(); }) .Configure(app => { diff --git a/Tests/MQTTnet.TestApp.AspNetCore2/MQTTnet.TestApp.AspNetCore2.csproj b/Tests/MQTTnet.TestApp.AspNetCore2/MQTTnet.TestApp.AspNetCore2.csproj index 5c0aacde..b5208f63 100644 --- a/Tests/MQTTnet.TestApp.AspNetCore2/MQTTnet.TestApp.AspNetCore2.csproj +++ b/Tests/MQTTnet.TestApp.AspNetCore2/MQTTnet.TestApp.AspNetCore2.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net461;netcoreapp2.1;netcoreapp3.1 Latest diff --git a/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs b/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs index 5248ce61..aed19b43 100644 --- a/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs +++ b/Tests/MQTTnet.TestApp.AspNetCore2/Program.cs @@ -1,19 +1,21 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using MQTTnet.AspNetCore; +using System.Threading.Tasks; namespace MQTTnet.TestApp.AspNetCore2 { public static class Program { - public static void Main(string[] args) + public static Task Main(string[] args) { - BuildWebHost(args).Run(); + return BuildWebHost(args).RunAsync(); } private static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) - .UseKestrel(o => { + .UseKestrel(o => + { o.ListenAnyIP(1883, l => l.UseMqtt()); o.ListenAnyIP(5000); // default http pipeline }) diff --git a/Tests/MQTTnet.TestApp.AspNetCore2/Startup.cs b/Tests/MQTTnet.TestApp.AspNetCore2/Startup.cs index 3a58acf7..0965f0d2 100644 --- a/Tests/MQTTnet.TestApp.AspNetCore2/Startup.cs +++ b/Tests/MQTTnet.TestApp.AspNetCore2/Startup.cs @@ -1,10 +1,13 @@ using System; using System.IO; +using System.Reflection; +using System.Runtime.Versioning; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Logging; using MQTTnet.AspNetCore; using MQTTnet.Server; @@ -16,29 +19,37 @@ namespace MQTTnet.TestApp.AspNetCore2 public void ConfigureServices(IServiceCollection services) { - var mqttServerOptions = new MqttServerOptionsBuilder() - .WithoutDefaultEndpoint() - .Build(); services - .AddHostedMqttServer(mqttServerOptions) + .AddHostedMqttServer(mqttServer => mqttServer.WithoutDefaultEndpoint()) .AddMqttConnectionHandler() .AddConnections(); } - // In class _Startup_ of the ASP.NET Core 2.0 project. + // In class _Startup_ of the ASP.NET Core 3.1 project. +#if NETCOREAPP3_1 + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapMqtt("/mqtt"); + }); +#else public void Configure(IApplicationBuilder app, IHostingEnvironment env) { - app.UseConnections(c => c.MapConnectionHandler("/mqtt", options => { - options.WebSockets.SubProtocolSelector = MQTTnet.AspNetCore.ApplicationBuilderExtensions.SelectSubProtocol; - })); + app.UseConnections(c => c.MapMqtt("/mqtt")); +#endif - //app.UseMqttEndpoint(); app.UseMqttServer(server => { server.StartedHandler = new MqttServerStartedHandlerDelegate(async args => { + var frameworkName = GetType().Assembly.GetCustomAttribute()? + .FrameworkName; + var msg = new MqttApplicationMessageBuilder() - .WithPayload("Mqtt is awesome") + .WithPayload($"Mqtt hosted on {frameworkName} is awesome") .WithTopic("message"); while (true) @@ -46,7 +57,7 @@ namespace MQTTnet.TestApp.AspNetCore2 try { await server.PublishAsync(msg.Build()); - msg.WithPayload("Mqtt is still awesome at " + DateTime.Now); + msg.WithPayload($"Mqtt hosted on {frameworkName} is still awesome at {DateTime.Now}"); } catch (Exception e) {