代码改变世界

MQTT学习(七)--使用MQTTNet+ASP.NET Core创建MQTT服务器(broker)

2023-10-11 17:20  古兆洋  阅读(1080)  评论(0编辑  收藏  举报

转自:https://blog.csdn.net/lordwish/article/details/86708777

经过漫长的等待,MQTT专题终于等到了第七篇,本次将在ASP.NET Core框架下利用MQTTnet创建自有服务器。

由于最近刚开始接触ASP.NET Core,很多具体的用法还没有研究透彻,所以本篇重点在核心的几段代码,示例参考了MQTTnet官方源码。

本示例将融合ASP.NET Core WebAPI,以便在API接口调用中实现消息推送。

1.创建项目并引用MQTTnet

 

在VS2017中新建ASP.NET Core Web应用程序,打开NuGet管理器,搜索并安装MQTTnet.AspNetCore。

2.实现MQTT服务器功能

2.1.启动配置项-Startup.cs
  1     public class Startup
  2     {
  3         public Startup(IConfiguration configuration)
  4         {
  5             Configuration = configuration;
  6         }
  7 
  8         public IConfiguration Configuration { get; }
  9 
 10         // This method gets called by the runtime. Use this method to add services to the container.
 11         public void ConfigureServices(IServiceCollection services)
 12         {
 13             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 14 
 15             #region MQTT配置
 16             string hostIp = Configuration["MqttOption:HostIp"];//IP地址
 17             int hostPort = int.Parse(Configuration["MqttOption:HostPort"]);//端口号
 18             int timeout = int.Parse(Configuration["MqttOption:Timeout"]);//超时时间
 19             string username = Configuration["MqttOption:UserName"];//用户名
 20             string password = Configuration["MqttOption:Password"];//密码
 21 
 22             //构建配置项
 23             var optionBuilder = new MqttServerOptionsBuilder()
 24                 .WithDefaultEndpointBoundIPAddress(System.Net.IPAddress.Parse(hostIp))
 25                 .WithDefaultEndpointPort(hostPort)
 26                 .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(timeout))
 27                 .WithConnectionValidator(t =>
 28                 {
 29                     if (t.Username != username || t.Password != password)
 30                     {
 31                         t.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
 32                     }
 33                     t.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
 34                 });
 35             var option = optionBuilder.Build();
 36 
 37             //服务注入
 38             services
 39                 .AddHostedMqttServer(option)
 40                 .AddMqttConnectionHandler()
 41                 .AddConnections();
 42             #endregion
 43 
 44         }
 45 
 46         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
 47         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 48         {
 49             if (env.IsDevelopment())
 50             {
 51                 app.UseDeveloperExceptionPage();
 52             }
 53 
 54             app.UseMvc();
 55 
 56 
 57             app.UseConnections(c => c.MapConnectionHandler<MqttConnectionHandler>("/data", options =>
 58             {
 59                 options.WebSockets.SubProtocolSelector = MQTTnet.AspNetCore.ApplicationBuilderExtensions.SelectSubProtocol;
 60             }));
 61 
 62             app.UseMqttEndpoint("/data");
 63             //MQTT声明周期事件
 64             app.UseMqttServer(server =>
 65             {
 66                 //服务启动事件
 67                 server.Started += async (sender, args) =>
 68                 {
 69                     var msg = new MqttApplicationMessageBuilder().WithPayload("welcome to mqtt").WithTopic("start");
 70                     while (true)
 71                     {
 72                         try
 73                         {
 74                             await server.PublishAsync(msg.Build());
 75                             msg.WithPayload("you are welcome to mqtt");
 76                         }
 77                         catch (Exception e)
 78                         {
 79                             Console.WriteLine(e);
 80                         }
 81                         finally
 82                         {
 83                             await Task.Delay(TimeSpan.FromSeconds(5));
 84                         }
 85                     }
 86                 };
 87                 //服务停止事件
 88                 server.Stopped += (sender, args) =>
 89                 {
 90 
 91                 };
 92 
 93                 //客户端连接事件
 94                 server.ClientConnected += (sender, args) =>
 95                 {
 96                     var clientId = args.ClientId;
 97                 };
 98                 //客户端断开事件
 99                 server.ClientDisconnected += (sender, args) =>
100                 {
101                     var clientId = args.ClientId;
102                 };
103 
104             });
105         }
106 
107     }
View Code
2.2.配置文件-appsetting.json
 1 {
 2   "Logging": {
 3     "LogLevel": {
 4       "Default": "Warning"
 5     }
 6   },
 7   "AllowedHosts": "*",
 8   "MqttOption": {
 9     "HostIp": "127.0.0.1",
10     "HostPort": 61613,
11     "Timeout": 5000,
12     "UserName": "admin",
13     "Password": "passwod"
14   }
15 }
2.3.程序入口-Program.cs
 1     public class Program
 2     {
 3         public static void Main(string[] args)
 4         {
 5             CreateWebHostBuilder(args).Build().Run();
 6             //上述方法与下方注释代码效果一致
 7             //WebHost
 8             //    .CreateDefaultBuilder(args)
 9             //    .UseKestrel()
10             //    .UseStartup<Startup>()
11             //    .Build()
12             //    .Run();
13         }
14 
15         public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
16             WebHost.CreateDefaultBuilder(args)
17                 .UseKestrel(o =>
18                 {
19                     o.ListenAnyIP(61613, m => m.UseMqtt());//绑定MQTT服务端口
20                     //o.ListenAnyIP(5000);
21                 })
22                 .UseStartup<Startup>();
23     }

3.在API接口中使用MQTT服务
由于ASP.NET Core使用依赖注入(Dependency Injection)来实现控制反转(IoC),MQTTServer正是通过依赖注入添加到应用程序的服务集合中去,同样通过ASP.NET Core中的机制可以在API控制器类中获取当前实例中的MQTT服务。具体实现要借助接口IServiceProvider。创建一个辅助类如下:

1     public static class ServiceLocator
2     {
3         public static IServiceProvider Instance { get; set; }
4     }

在Startup类的Configure方法中添加如下代码:

1 //获取当前应用的服务集合
2 ServiceLocator.Instance = app.ApplicationServices;

在API控制器中就可以通过ServiceLocator获取服务并使用了。

 1     [Route("v1/api/values")]
 2     [ApiController]
 3     public class ValuesController : RootController
 4     {
 5 
 6         public string Test()
 7         {
 8             string result = "";
 9             //从服务集合中获取MQTT服务
10             var service = ServiceLocator.Instance.GetService(typeof(MQTTnet.Server.MqttServer));
11             var messager = (MQTTnet.Server.MqttServer)service;
12             
13             //这里你可以构建消息并发布
14 
15             return result;
16         }
17     }

示例代码

经过上述过程中的探索研究,虽然暂未实现图形化界面,但基本了解了如何使用ASP.NET Core构建MQTT代理服务器,同时掌握了在API接口中使用MQTT服务的方法,后续将做更深一步的研究。
————————————————
版权声明:本文为CSDN博主「ludewig」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lordwish/article/details/86708777