Abp vNext 集成 MQTT
- Abp vNext 集成 MQTT
- Broker
- ApsNet Core 集成 MQTT
- 引用包
- 添加服务
- 添加 MQTT Endpoint
- 设置 MQTT监听端口
- 修复 Http和Https 的监听端口
- ApsNet Core 集成 MQTT
- Broker
Abp vNext 集成 MQTT
Broker
ApsNet Core 集成 MQTT
引用包
re>
添加服务
代码清单:Artisan.IotHub.HttpApi.Host/IotHubHttpApiHostModule.cs
public override void ConfigureServices(ServiceConfigurationContext context) { // ...... ConfigureMqttService(context, configuration); } private void ConfigureMqttService(ServiceConfigurationContext context, IConfiguration configuration) { var settings = configuration.GetSection("MqttServer").Get
re>(); context.Services.ConfigureMqttService(settings); } appsettings.json 中的配置:
"MqttServer": { "IpAddress": "localhost", "DomainName": "", "Port": 2883, "EnableTls": false, "TlsPort": 8883 },
re>其中:
方法
ConfigureMqttServic()
是扩展方法,如下所示:代码清单:Artisan.IotHub.Application/Mqtts/Extensions/MqttConfiguration.cs
public static class MqttConfiguration { public static void ConfigureMqttService( this IServiceCollection services, MqttServerSettings settings) { services.AddHostedMqttServerWithServices(options => { options.WithDefaultEndpointPort(settings.Port).WithDefaultEndpoint(); var mqttService = services.GetRequiredService
re>(); mqttService.ConfigureMqttServerOptions(options); }); services.AddMqttConnectionHandler(); services.AddMqttWebSocketServerAdapter(); services.AddConnections(); } // ..... } 添加 MQTT Endpoint
代码清单:Artisan.IotHub.HttpApi.Host/IotHubHttpApiHostModule.cs
public override void OnApplicationInitialization(ApplicationInitializationContext context) { app.UseAbpRequestLocalization(); app.UseCorrelationId(); app.UseStaticFiles(); app.UseRouting(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); // 添加 MQTT 中间件 app.UseMqttServer(); app.UseSwagger(); }
re>其中:方法
UseMqttServe()
是自定义的扩展方法,如下所示:代码清单:Artisan.IotHub.Application/Mqtts/Extensions/MqttConfiguration.cs
public static class MqttConfiguration { //...... public static void UseMqttServer(this IApplicationBuilder app) { app.UseMqttServer(mqttServer => { app.ApplicationServices .GetRequiredService
re>() .ConfigureMqttServer(mqttServer); }); app.UseEndpoints(endpoint => { endpoint.MapMqtt("/mqtt"); }); } } ConfigureMqttServer()调用:
代码清单:Artisan.IotHub.Application/Mqtts/MqttServerService.cs
public class MqttServerService : IMqttServerService, ISingletonDependency { private readonly IMqttConnectionService _mqttConnectionService; private readonly IMqttSubscriptionService _mqttSubscriptionService; private readonly IMqttPublishingService _mqttPublishingService; public MqttServerService( IMqttConnectionService mqttConnectionService, IMqttSubscriptionService mqttSubscriptionService, IMqttPublishingService mqttPublishingService) { _mqttConnectionService = mqttConnectionService; _mqttSubscriptionService = mqttSubscriptionService; _mqttPublishingService = mqttPublishingService; } public void ConfigureMqttServer(IMqttServer mqttServer) { _mqttConnectionService.ConfigureMqttServer(mqttServer); _mqttSubscriptionService.ConfigureMqttServer(mqttServer); _mqttPublishingService.ConfigureMqttServer(mqttServer); } public void ConfigureMqttServerOptions(AspNetMqttServerOptionsBuilder options) { _mqttConnectionService.ConfigureMqttServerOptions(options); _mqttSubscriptionService.ConfigureMqttServerOptions(options); _mqttPublishingService.ConfigureMqttServerOptions(options); options.WithoutDefaultEndpoint(); } }
re>设置 MQTT监听端口
通过ConfigureKestrel()方法在 Kestrel 上设置MQTT的监听端口,如下代码所示:
代码清单:Artisan.IotHub.HttpApi.Host/Program.cs
var builder = WebApplication.CreateBuilder(args); // ...... builder.WebHost.ConfigureKestrel(option => { option.ConfigureMqttServer(); });
re>其中:方法
ConfigureMqttServer()
是扩展方法,如下所示:代码清单:Artisan.IotHub.HttpApi.Host/KestrelServerOptionsExtensions.cs
public static class KestrelServerOptionsExtensions { ///
re>/// 在 KestrelServer 中设置 MqttServer 的监听端口 /// /// aram> public static void ConfigureMqttServer(this KestrelServerOptions option) { var configuration = option.ApplicationServices.GetRequiredService(); var mqttSettings = configuration.GetSection("MqttServer").Get (); //option.ListenAnyIP(mqttSettings.Port, opt => opt.UseMqtt()); if (mqttSettings.IpAddress.ToLower() == "localhost") { option.ListenLocalhost(mqttSettings.Port, opt => opt.UseMqtt()); } else { option.Listen( IPAddress.Parse(mqttSettings.IpAddress), mqttSettings.Port, opt => opt.UseMqtt() ); } } } 修复 Http和Https 的监听端口
通过ConfigureKestrel()方法在 Kestrel 上设置MQTT的监听端口,如下代码所示:
builder.WebHost.ConfigureKestrel(option => { option.ConfigureMqttServer(); }); => option.Listen( IPAddress.Parse(mqttSettings.IpAddress), mqttSettings.Port, opt => opt.UseMqtt() );
re>但是这样做,会出现一个Bug:Http和Https 的监听端口将会失效 !!!,
通过Http和Https 监听端口(比如:https://localhost:44359)是无法访问 Api的。原因:
通过 ConfigureKestrel() 方法在 Kestrel 上设置的Http和Https 监听端口后,其它地方设置(例如:在launchSettings.json 文件)的监听方式会被覆盖而失效!
而我们又没有在ConfigureKestrel()的方法中重新设置Http和Https 的监听端口。
如何修复呢?
可通过修改配置文件
appsettings.json
来设置Http和Https的监听端口,具体操作如下:在配置文件
appsettings.json
中添加如下 Kestrel 配置节点:{ "Kestrel": { "Endpoints": { "Http": { "Url": "http://localhost:7059", "Protocols": "Http1AndHttp2" }, "Https": { "Url": "https://localhost:44359", "Protocols": "Http1AndHttp2" }, } } // ..... }
re>这样就通过配置文件的方式为Kestrel 设置了Http和Https的监听端口