Skip to content

Commit 29c84af

Browse files
committed
Upgraded to .Net 6 and to MqttNet 4
1 parent 276b780 commit 29c84af

14 files changed

+88
-66
lines changed

ExampleClient/ExampleClient.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<TargetFramework>net6.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="3.0.16" />
9+
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="4.0.1.184" />
1010
</ItemGroup>
1111

1212
</Project>

ExampleClient/Program.cs

+29-19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using MQTTnet;
2-
using MQTTnet.Client.Options;
2+
using MQTTnet.Client;
33
using MQTTnet.Extensions.ManagedClient;
4+
using MQTTnet.Packets;
45
using System;
6+
using System.Collections.Generic;
57

68
namespace ExampleClient
79
{
@@ -20,35 +22,43 @@ private static async System.Threading.Tasks.Task Main(string[] args)
2022
.Build();
2123

2224
var mqttClient = new MqttFactory().CreateManagedMqttClient();
23-
await mqttClient.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("MqttWeatherForecast/90210/temperature").Build());
25+
await mqttClient.SubscribeAsync(new List<MqttTopicFilter> { new MqttTopicFilterBuilder().WithTopic("MqttWeatherForecast/90210/temperature").Build() });
2426

25-
mqttClient.UseConnectedHandler(e =>
27+
mqttClient.ConnectedAsync += (e) =>
2628
{
27-
Console.WriteLine($"Connection Result: {e.AuthenticateResult.ResultCode}");
28-
});
29+
Console.WriteLine($"Connection Result: {e.ConnectResult.ResultCode}");
30+
return System.Threading.Tasks.Task.CompletedTask;
31+
};
2932

30-
mqttClient.UseApplicationMessageReceivedHandler(e =>
33+
mqttClient.ConnectingFailedAsync += (e) =>
34+
{
35+
Console.WriteLine($"Connection Failed: {e.Exception}");
36+
return System.Threading.Tasks.Task.CompletedTask;
37+
};
38+
39+
mqttClient.ApplicationMessageReceivedAsync += e =>
3140
{
3241
Console.WriteLine($"Message from {e.ClientId}: {e.ApplicationMessage.Payload.Length} bytes.");
33-
});
42+
return System.Threading.Tasks.Task.CompletedTask;
43+
};
3444

3545
await mqttClient.StartAsync(options);
3646

3747
// Publish a message on a well known topic
38-
await mqttClient.PublishAsync(new ManagedMqttApplicationMessageBuilder().WithApplicationMessage(msg =>
39-
{
40-
msg.WithAtLeastOnceQoS();
41-
msg.WithPayload(BitConverter.GetBytes(98.6d));
42-
msg.WithTopic("MqttWeatherForecast/90210/temperature");
43-
}).Build());
48+
await mqttClient.EnqueueAsync(new ManagedMqttApplicationMessageBuilder().WithApplicationMessage(msg =>
49+
{
50+
msg.WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);
51+
msg.WithPayload(BitConverter.GetBytes(98.6d));
52+
msg.WithTopic("MqttWeatherForecast/90210/temperature");
53+
}).Build());
4454

4555
// Publish a message on a topic the server doesn't explicitly handle
46-
await mqttClient.PublishAsync(new ManagedMqttApplicationMessageBuilder().WithApplicationMessage(msg =>
47-
{
48-
msg.WithAtLeastOnceQoS();
49-
msg.WithPayload(BitConverter.GetBytes(100d));
50-
msg.WithTopic("asdfsdfsadfasdf");
51-
}).Build());
56+
await mqttClient.EnqueueAsync(new ManagedMqttApplicationMessageBuilder().WithApplicationMessage(msg =>
57+
{
58+
msg.WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);
59+
msg.WithPayload(BitConverter.GetBytes(100d));
60+
msg.WithTopic("asdfsdfsadfasdf");
61+
}).Build());
5262

5363
// StartAsync returns immediately, as it starts a new thread using Task.Run, and so the calling thread needs
5464
// to wait.

ExampleServer/Controllers/WeatherForecastController.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Threading.Tasks;
54
using Microsoft.AspNetCore.Mvc;
65
using Microsoft.Extensions.Logging;
76

ExampleServer/ExampleServer.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp3.1</TargetFramework>
4+
<TargetFramework>net6.0</TargetFramework>
55
</PropertyGroup>
66

77
<ItemGroup>

ExampleServer/Program.cs

+12-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.Extensions.Configuration;
77
using Microsoft.Extensions.Hosting;
88
using Microsoft.Extensions.Logging;
9+
using MQTTnet.AspNetCore;
910

1011
namespace Example
1112
{
@@ -18,9 +19,16 @@ public static void Main(string[] args)
1819

1920
public static IHostBuilder CreateHostBuilder(string[] args) =>
2021
Host.CreateDefaultBuilder(args)
21-
.ConfigureWebHostDefaults(webBuilder =>
22-
{
23-
webBuilder.UseStartup<Startup>();
24-
});
22+
.ConfigureWebHostDefaults(webBuilder =>
23+
{
24+
webBuilder.UseKestrel(
25+
o =>
26+
{
27+
o.ListenAnyIP(50483, l => l.UseMqtt()); // MQTT pipeline
28+
o.ListenAnyIP(50482); // Default HTTP pipeline
29+
});
30+
webBuilder.ConfigureLogging(opts => opts.AddConsole());
31+
webBuilder.UseStartup<Startup>();
32+
});
2533
}
2634
}

ExampleServer/Properties/launchSettings.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{
1+
{
22
"$schema": "http://json.schemastore.org/launchsettings.json",
33
"iisSettings": {
44
"windowsAuthentication": false,
@@ -21,10 +21,9 @@
2121
"commandName": "Project",
2222
"launchBrowser": true,
2323
"launchUrl": "weatherforecast",
24-
"applicationUrl": "http://localhost:5000",
2524
"environmentVariables": {
2625
"ASPNETCORE_ENVIRONMENT": "Development"
2726
}
2827
}
2928
}
30-
}
29+
}

ExampleServer/Startup.cs

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
using System.Linq;
12
using Microsoft.AspNetCore.Builder;
23
using Microsoft.AspNetCore.Hosting;
34
using Microsoft.Extensions.Configuration;
45
using Microsoft.Extensions.DependencyInjection;
56
using Microsoft.Extensions.Hosting;
67
using MQTTnet.AspNetCore;
78
using MQTTnet.AspNetCore.AttributeRouting;
8-
using MQTTnet.AspNetCore.Extensions;
9+
using MQTTnet.Server;
910

1011
namespace Example
1112
{
@@ -24,17 +25,15 @@ public void ConfigureServices(IServiceCollection services)
2425
// Configure AspNetCore controllers
2526
services.AddControllers();
2627

28+
services.AddSingleton<MqttServer>();
29+
2730
// Identify and build routes for the current assembly
2831
services.AddMqttControllers();
29-
3032
services
3133
.AddHostedMqttServerWithServices(s =>
3234
{
3335
// Optionally set server options here
3436
s.WithoutDefaultEndpoint();
35-
36-
// Enable Attribute routing
37-
s.WithAttributeRouting(allowUnmatchedRoutes: true);
3837
})
3938
.AddMqttConnectionHandler()
4039
.AddConnections();
@@ -57,7 +56,15 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
5756
endpoints.MapControllers();
5857

5958
// Root endpoint for MQTT - attribute routing picks up after this URL
60-
endpoints.MapMqtt("/mqtt");
59+
endpoints.MapConnectionHandler<MqttConnectionHandler>(
60+
"/mqtt",
61+
opts => opts.WebSockets.SubProtocolSelector = protocolList => protocolList.FirstOrDefault() ?? string.Empty);
62+
});
63+
64+
app.UseMqttServer(server =>
65+
{
66+
// Enable Attribute routing
67+
server.WithAttributeRouting(app.ApplicationServices, true);
6168
});
6269
}
6370
}

Source/Extensions/ServiceCollectionExtensions.cs

+6-7
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,13 @@ public static IServiceCollection AddMqttControllers(this IServiceCollection serv
3838
return services;
3939
}
4040

41-
public static AspNetMqttServerOptionsBuilder WithAttributeRouting(this AspNetMqttServerOptionsBuilder options, bool allowUnmatchedRoutes = false)
41+
public static void WithAttributeRouting(this MqttServer server, IServiceProvider svcProvider, bool allowUnmatchedRoutes = false)
4242
{
43-
var router = options.ServiceProvider.GetRequiredService<MqttRouter>();
44-
var interceptor = new MqttServerApplicationMessageInterceptorDelegate(context => router.OnIncomingApplicationMessage(options, context, allowUnmatchedRoutes));
45-
46-
options.WithApplicationMessageInterceptor(interceptor);
47-
48-
return options;
43+
var router = svcProvider.GetRequiredService<MqttRouter>();
44+
server.InterceptingPublishAsync += async (args) =>
45+
{
46+
await router.OnIncomingApplicationMessage(svcProvider, args, allowUnmatchedRoutes);
47+
};
4948
}
5049
}
5150
}

Source/MQTTnet.AspNetCore.AttributeRouting.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net5.0</TargetFrameworks>
4+
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
55
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
66
<Description>
77
This is a support library to integrate AttributeRouting into MQTTnet with AspNetCore.
@@ -42,7 +42,7 @@
4242
<ItemGroup>
4343
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
4444
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
45-
<PackageReference Include="MQTTnet" Version="3.0.16" />
46-
<PackageReference Include="MQTTnet.AspNetCore" Version="3.0.16" />
45+
<PackageReference Include="MQTTnet" Version="4.0.1.184" />
46+
<PackageReference Include="MQTTnet.AspNetCore" Version="4.0.1.184" />
4747
</ItemGroup>
4848
</Project>

Source/Routing/IMqttControllerContext.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace MQTTnet.AspNetCore.AttributeRouting.Routing
66
{
77
public interface IMqttControllerContext
88
{
9-
MqttApplicationMessageInterceptorContext MqttContext { get; set; }
10-
IMqttServer MqttServer { get; set; }
9+
InterceptingPublishEventArgs MqttContext { get; set; }
10+
MqttServer MqttServer { get; set; }
1111
}
1212
}

Source/Routing/MqttBaseController.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public abstract class MqttBaseController
1414
/// <summary>
1515
/// Connection context is set by controller activator. If this class is instantiated directly, it will be null.
1616
/// </summary>
17-
public MqttApplicationMessageInterceptorContext MqttContext => ControllerContext.MqttContext;
17+
public InterceptingPublishEventArgs MqttContext => ControllerContext.MqttContext;
1818

1919
/// <summary>
2020
/// Gets the <see cref="MqttApplicationMessage"/> for the executing action.
@@ -24,7 +24,7 @@ public abstract class MqttBaseController
2424
/// <summary>
2525
/// Gets the <see cref="MqttServer"/> for the executing action.
2626
/// </summary>
27-
public IMqttServer Server => ControllerContext.MqttServer;
27+
public MqttServer Server => ControllerContext.MqttServer;
2828

2929
/// <summary>
3030
/// ControllerContext is set by controller activator. If this class is instantiated directly, it will be null.
@@ -39,7 +39,7 @@ public abstract class MqttBaseController
3939
[NonAction]
4040
public virtual Task Ok()
4141
{
42-
MqttContext.AcceptPublish = true;
42+
MqttContext.ProcessPublish = true;
4343
return Task.CompletedTask;
4444
}
4545

@@ -58,7 +58,7 @@ public virtual Task Ok()
5858
[NonAction]
5959
public virtual Task BadMessage()
6060
{
61-
MqttContext.AcceptPublish = false;
61+
MqttContext.ProcessPublish = false;
6262
return Task.CompletedTask;
6363
}
6464
}

Source/Routing/MqttControllerContext.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace MQTTnet.AspNetCore.AttributeRouting.Routing
66
{
77
public class MqttControllerContext : IMqttControllerContext
88
{
9-
public MqttApplicationMessageInterceptorContext MqttContext { get; set; }
10-
public IMqttServer MqttServer { get; set; }
9+
public InterceptingPublishEventArgs MqttContext { get; set; }
10+
public MqttServer MqttServer { get; set; }
1111
}
1212
}

Source/Routing/MqttRouter.cs

+8-8
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public MqttRouter(ILogger<MqttRouter> logger, MqttRouteTable routeTable, ITypeAc
2727
this.typeActivator = typeActivator;
2828
}
2929

30-
internal async Task OnIncomingApplicationMessage(AspNetMqttServerOptionsBuilder options, MqttApplicationMessageInterceptorContext context, bool allowUnmatchedRoutes)
30+
internal async Task OnIncomingApplicationMessage(IServiceProvider svcProvider, InterceptingPublishEventArgs context, bool allowUnmatchedRoutes)
3131
{
3232
// Don't process messages sent from the server itself. This avoids footguns like a server failing to publish
3333
// a message because a route isn't found on a controller.
@@ -48,11 +48,11 @@ internal async Task OnIncomingApplicationMessage(AspNetMqttServerOptionsBuilder
4848
logger.LogDebug($"Rejecting message publish because '{context.ApplicationMessage.Topic}' did not match any known routes.");
4949
}
5050

51-
context.AcceptPublish = allowUnmatchedRoutes;
51+
context.ProcessPublish = allowUnmatchedRoutes;
5252
}
5353
else
5454
{
55-
using (var scope = options.ServiceProvider.CreateScope())
55+
using (var scope = svcProvider.CreateScope())
5656
{
5757
Type? declaringType = routeContext.Handler.DeclaringType;
5858

@@ -83,7 +83,7 @@ internal async Task OnIncomingApplicationMessage(AspNetMqttServerOptionsBuilder
8383
var controllerContext = new MqttControllerContext()
8484
{
8585
MqttContext = context,
86-
MqttServer = scope.ServiceProvider.GetRequiredService<IMqttServer>()
86+
MqttServer = scope.ServiceProvider.GetRequiredService<MqttServer>()
8787
};
8888

8989
for (int i = 0; i < activateProperties.Length; i++)
@@ -94,7 +94,7 @@ internal async Task OnIncomingApplicationMessage(AspNetMqttServerOptionsBuilder
9494

9595
ParameterInfo[] parameters = routeContext.Handler.GetParameters();
9696

97-
context.AcceptPublish = true;
97+
context.ProcessPublish = true;
9898

9999
if (parameters.Length == 0)
100100
{
@@ -114,20 +114,20 @@ internal async Task OnIncomingApplicationMessage(AspNetMqttServerOptionsBuilder
114114
{
115115
logger.LogError(ex, $"Unable to match route parameters to all arguments. See inner exception for details.");
116116

117-
context.AcceptPublish = false;
117+
context.ProcessPublish = false;
118118
}
119119
catch (TargetInvocationException ex)
120120
{
121121
logger.LogError(ex.InnerException, $"Unhandled MQTT action exception. See inner exception for details.");
122122

123123
// This is an unandled exception from the invoked action
124-
context.AcceptPublish = false;
124+
context.ProcessPublish = false;
125125
}
126126
catch (Exception ex)
127127
{
128128
logger.LogError(ex, "Unable to invoke Mqtt Action. See inner exception for details.");
129129

130-
context.AcceptPublish = false;
130+
context.ProcessPublish = false;
131131
}
132132
}
133133
}

Tests/MQTTnetA.AspNetCore.AttributeRouting.Tests/MQTTnet.AspNetCore.AttributeRouting.Tests.csproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netcoreapp3.1;net461;net5.0</TargetFrameworks>
4+
<TargetFrameworks>netcoreapp3.1;net461;net5.0;net6.0</TargetFrameworks>
55

66
<IsPackable>false</IsPackable>
77

@@ -15,9 +15,9 @@
1515
</PropertyGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
19-
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
20-
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
18+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
19+
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
20+
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
2121
</ItemGroup>
2222

2323
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">

0 commit comments

Comments
 (0)