隐藏

C# 完美实现物联网 MQTT 数据通信

发布:2024/3/21 23:10:32作者:管理员 来源:本站 浏览次数:574

前言


MQTT 协议由于其用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务,具有开销低、占用带宽低、即时通讯等优点,使其在物联网、小型设备、移动应用等方面有较广泛的应用,在工业物联网中,MQTT也有广泛的应用。

Step By Step 步骤


   搭建一个 MQTT 服务器

       见本人其它文章《手把手教你在 Windows 环境中搭建 MQTT 服务器》


   创建一个 .Net Framework Console 项目,命名为 MQTTSample


   添加 NuGet 包


   <package id="MQTTnet" version="4.3.1.873" targetFramework="net48" />

   <package id="MQTTnet.Extensions.WebSocket4Net" version="4.3.1.873" targetFramework="net48" />


   注:在添加这两个包时,会自动添加其它依赖包


   在 Program.cs 编写 MQTT 通信(重点看注释)


   using System;

   using System.Collections.Generic;

   using System.Linq;

   using System.Text;

   using System.Threading.Tasks;

   using MQTTnet;

   using MQTTnet.Client;

   using MQTTnet.Packets;

   using MQTTnet.Protocol;

   using System.Security.Authentication;

   using MQTTnet.Formatter;

   using MQTTnet.Extensions.WebSocket4Net;

   using System.Threading;


   namespace MQTTSample

   {

    internal class Program

    {

    static async Task Main(string[] args)

    {

    // 设计两个参数,是为了可以打开两个 CMD 客户端进行测试

    if (args[0] == "publish")

    {

    Console.WriteLine("Publish message...");

    await PublishMessage();

    }

    else

    {

    Console.WriteLine("Receive message...");

    await SubscribeTopic();

    }  

    }


    // 循环不断地发布消息

    private static async Task PublishMessage()

    {

    var i = 0;

    while (i <= 1000)

    {

    var mqttFactory = new MqttFactory();


    using (var mqttClient = mqttFactory.CreateMqttClient())

    {

    // 1. 连接 MQTT 服务器

    var mqttClientOptions = new MqttClientOptionsBuilder()

    .WithTcpServer("192.168.3.233", 1883) // MQTT 服务器IP+端口

    .WithClientId("publish_client") // 客户端名称

    //.WithProtocolVersion(MqttProtocolVersion.V500)

    //.WithCleanSession()

    .Build();


    var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);


    Console.WriteLine($"The MQTT client is connected. IsConnected: [{mqttClient.IsConnected}]");

    Console.WriteLine(response.ResultCode);


    // 2. 发布消息

    // 2.1 在名为 topic2 的主题上发布消息 this is a test message

    var applicationMessage = new MqttApplicationMessageBuilder()

    .WithTopic("topic2")

    .WithPayload("this is a test message")

    .Build();


    // 2.2 异步发布消息

    await mqttClient.PublishAsync(applicationMessage, CancellationToken.None);


    // 3. 断开连接

    await mqttClient.DisconnectAsync();


    Console.WriteLine("MQTT application message is published.");

    }


    i++;

    Thread.Sleep(1000);

    }

    }


    // 订阅消息

    // 订阅一次就可以,不需要循环

    // 当订阅的主题有发布消息时,这个程序就可以接收到

    private static async Task SubscribeTopic()

    {

    var mqttFactory = new MqttFactory();


    using (var mqttClient = mqttFactory.CreateMqttClient())

    {

    // 1. 设置连接 MQTT 服务器的属性

    var mqttClientOptions = new MqttClientOptionsBuilder()

    .WithTcpServer("192.168.3.233", 1883)

    .WithClientId("subscribe_client")

    //.WithCleanSession()

    .Build();


    // 2. 定义一个事件,当订阅的主题有发布消息时,接收并打印消息

    // 2.1 这段代码必须写在连接 MQTT 服务器的代码之前,才能确保可以接收到消息

    mqttClient.ApplicationMessageReceivedAsync += e =>

    {

    Console.WriteLine("Received application message.");

    Console.WriteLine(e.ApplicationMessage.Topic);

    Console.WriteLine(Encoding.UTF8.GetString(e.ApplicationMessage.Payload));

    Console.WriteLine("===================");


    return Task.CompletedTask;

    };

   

    // 3. 连接 MQTT 服务器

    await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);



    // 4. 订阅名为 topic2 的主题的消息

    var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()

    .WithTopicFilter(

    f =>

    {

    f.WithTopic("topic2")      

    .WithExactlyOnceQoS(); //即精准一次

    })

    .Build();


    await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);


    Console.WriteLine("MQTT client subscribed to topic.");


    // 5. 离开时才断开连接

    Console.WriteLine("Press enter to exit.");

    Console.ReadLine();

    }


    }

    }

   }


   编译并运行测试


       打开一个 CMD 命令窗口,姑且称为 CMD1,定位到 MQTTSample.exe 所有目录,如


       cd D:\MQTTSample\MQTTSample\bin\Debug


       运行以下命令,运行 MQTT 接收订阅消息客户端


       MQTTSample.exe subscribe


       注:这个时候,还没有运行 MQTT 发布消息客户端,MQTT 接收订阅消息客户端 还没有显示接收的消息


       重新打开一个 CMD 命令窗口,姑且称为 CMD2,定位到 MQTTSample.exe 所有目录


       运行以下命令,运行 MQTT 发布消息客户端


       MQTTSample.exe publish


       注:此时,按照程序设定,MQTT 发布消息客户端 每隔 1 秒不断发布消息:this is a test message


       此时,CMD1 窗口的 MQTT 接收订阅消息客户端 也会不停地显示其接收的消息:this is a test message


       至此,说明此 "MQTT 通信" 程序的两个不同客户端成功利用 MQTT 服务器进行通信