目录
在物联网项目中, 处理MQTT的topic时费工费力, 代码一团乱, 什么才是最好的姿势?这里面我们极力介绍 MQTTnet.AspNetCore.Routing 项目,MQTTnet AspNetCore Routing 是https://github.com/Atlas-LiftTech/MQTTnet.AspNetCore.AttributeRouting 的分支项目。这个组件是通过MQTTnet 实现了定义控制类和属性来路由处理消息的topic , 就像Asp.Net Core 的WebApi 写法一样简单容易。
为什么要用这个库?
这个库完全是一个MQTTnet的可选扩展 ,但如果你恰好有如下需求:
-
你的主要需求是在服务器上验证和处理MQTT消息。
-
你的服务器并不主要用于向客户端发送消息。
-
您喜欢以类似于 AspNetCore 和 WebAPI 的方式将消息处理逻辑封装在控制器中。
您可以自己使用 MQTTnet 委托直接执行此插件执行的所有操作。但是,随着您为验证或处理传入消息而编写的逻辑量增加,将逻辑组织到控制器中的能力开始变得更加有意义。该库有助于组织该代码,并将依赖项注入框架整合到MQTTnet中。
功能
-
将传入消息逻辑封装在控制器中
-
在 MQTT 逻辑中使用 AspNetCore 中熟悉的范例(Controllers 和 Actions)
-
在 AspNetCore 项目中使用现有的 ServiceProvider 实现对依赖注入的一流支持
-
支持控制器上的同步和async/await操作
-
与任何其他 MQTTnet 选项一起使用
性能说明
此库尚未针对非常高负载的环境进行测试。确保在生产中使用之前执行自己的负载测试。欢迎所有性能改进 PR。
支持的框架
-
.NET Standard 2.0+
-
.NET Core 3.1+
支持的MQTT版本
-
5.0.0
-
3.1.1
-
3.1.0
Nuget 和仓库地址
Nutget: https://www.nuget.org/packages/MQTTnet.AspNetCore.Routing/
https://gitee.com/IoTSharp/MQTTnet.AspNetCore.Routing
https://github.com/IoTSharp/MQTTnet.AspNetCore.Routing
使用方法
从nuget安装此包和MQTTnet。dotnet CLI:
dotnet add package MQTTnet.AspNetCore.Routing
ASP.NET Core 6 MVC 配置示例
using MQTTnet.AspNetCore;
using MQTTnet.AspNetCore.Routing;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(o =>
{
o.ListenAnyIP(iotaboardMqttSettings.Port, l => l.UseMqtt());
o.ListenAnyIP(iotaboardHttpSettings.Port);
}
);
//配置MQTT服务
builder.Services
.AddHostedMqttServerWithServices(o =>
{
// other configurations
o.WithoutDefaultEndpoint();
})
.AddMqttConnectionHandler()
.AddConnections()
.AddMqttControllers( // <== NOTICE THIS PART
/*
默认情况下,所有控制类在这里都会被自动发现, 那么这里就是空的, 但是这里也提供了加入其他程序集的方法。
*/);
var app = builder.Build();
app.MapControllers();
app.UseMqttServer(server => {
// other MqttServer configurations, for example client connect intercepts
server.WithAttributeRouting(app.Services, allowUnmatchedRoutes: false);
});
app.Run();
创建你的控制器, 集成 MqttBaseController 并添加方法像下面这样:
[MqttController]
[MqttRoute("[controller]")] // 指定控制类topic 。
public class MqttWeatherForecastController : MqttBaseController
{
private readonly ILogger<MqttWeatherForecastController> _logger;
// Controllers支持完整的注入依赖, 就像AspNetCore 控制器一样。
public MqttWeatherForecastController(ILogger<MqttWeatherForecastController> logger)
{
_logger = logger;
}
//支持模板路由和类型定义就像AspNetCore一样。
// Action 路由与控制器级别的路由前缀一起组成
[MqttRoute("{zipCode:int}/temperature")]
public Task WeatherReport(int zipCode)
{
// 我们这里可以直接访问MqttContext
if (zipCode != 90210) { MqttContext.CloseConnection = true; }
// 我们可以直接访问原始数据
var temperature = BitConverter.ToDouble(Message.Payload);
_logger.LogInformation($"It's {temperature} degrees in Hollywood");
// 规则判断
if (temperature <= 0 || temperature >= 130)
{
return BadMessage();
}
return Ok();
}
//我们也支持 FromPayload , 就像 AspNetCore中的FromBody 一样。
[MqttRoute("viewmodel/{sender}")]
public Task DeserializeViewModel(string sender, [FromPayload] SamplePayload payload)
{
_logger.LogInformation("{Sender} says {Message}", sender, payload.Message);
return Accepted();
}
}
public class SamplePayload
{
public string Message { get; set; }
}