C# MQTT with MQTTnet lib

C# MQTT with MQTTnet lib

MQTTnet

MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker). The implementation is based on the documentation from http://mqtt.org/.

  • 重點是有提供client與server的機制,目前支持新版的 .NET core,這是選擇 MQTTnet 的原因

Server 端 (MQTT broker)

MQTT 服務端主要用於與多個用戶端保持連接,並處理用戶端的發佈和訂閱等邏輯。一般很少直接從服務端發送消息給用戶端(以 mqttServer.Publish(appMsg) 直接發送消息),多數情況下服務端都是轉發主題匹配的用戶端消息,在系統中起到一個中介的作用。

服務端

創建服務端是採用 MqttFactory物件的 CreateMqttServer 方法來實現,該方法需要一個MqttServerOptions() 或是 MqttServerOptionsBuilder()。

var options = new MqttServerOptions();
var mqttServer = new MqttFactory().CreateMqttServer(options);

調用其 StartAsync 方法即可啟動 MQTT 服務

await mqttServer.StartAsync(options);

在 MqttServerOptions 選項中,可以使用 ConnectionValidator 來對用戶端連接進行驗證。比如用戶端ID標識 ClientId,用戶名 Username 和密碼 Password 等。

 var options = new MqttServerOptions()
               {
                   ConnectionValidator = c =>
                   {
                       if (c.ClientId.Length < 10)
                       {
                           c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected;
                           return;
                       }

                       if (c.Username != username)
                       {
                           c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
                           return;
                       }

                       if (c.Password != passsword)
                       {
                           c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
                           return;
                       }

                       c.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
                   }
               };

服務端支援 ClientConnected、ClientDisconnected 和 ApplicationMessageReceived 事件,分別用來檢查用戶端連接、用戶端斷開以及接收用戶端發來的消息。

其中 ClientConnected 和 ClientDisconnected 事件的事件參數一個用戶端連線物件 ConnectedMqttClient,通過該物件可以獲取Client Id 和 MQTT 版本 ProtocolVersion。

ApplicationMessageReceived 的事件參數包含了 Client Id 和 MQTT 應用消息 MqttApplicationMessage 物件,通過該物件可以獲取主題 Topic、QoS QualityOfServiceLevel 和消息內容 Payload 等資訊。

Client 端

MQTT 是基於發佈/訂閱模式的,所有的用戶端均與服務端保持連接狀態。

那麼用戶端之間是如何通信的呢?

用戶端向服務端訂閱它感興趣(主題)的消息,另一些用戶端向服務端發佈(主題)消息,服務端將訂閱和發佈的主題進行匹配,並將消息轉發給匹配通過的用戶端。

用戶端

採用 MqttFactory物件的 CreateMqttClient 方法

mqttClient = new MqttFactory().CreateMqttClient()

調用其 ConnectAsync 方法即可啟動 MQTT 服務

await mqttClient.ConnectAsync(options);

調用該方法時需要傳遞一個 MqttClientOptions 物件,該選項包含了 Client Id、broker address(可以使用IP位址或功能變數名稱)Server、埠號 Port、用戶名 UserName、密碼 Password 等資訊。

改版後, 將原本物件改成了多個物件實現
MqttClientCredentials() : username, password
MqttClientTcpOptions() : server address, port

 var options = new MqttClientOptions
            {
                ClientId = "aaa123456",
                Credentials = new MqttClientCredentials
                {
                    Username = username,
                    Password = passsword
                },
                ChannelOptions = new MqttClientTcpOptions
                {
                    Server = brokerAddress,
                    Port = brokerPort,
                }
            };

用戶端支援 Connected、Disconnected 和 ApplicationMessageReceived 事件,用來處理用戶端與服務端連接、用戶端從服務端斷開以及用戶端收到消息的事情。

訂閱消息

用戶端連接到服務端之後,可以使用 SubscribeAsync() 非同步方法訂閱消息,該方法可以傳入TopicFilter 參數,包含主題 Topic 和 QoS。

mqttClient.SubscribeAsync(new List<TopicFilter> {
                new TopicFilter("Topic name", MqttQualityOfServiceLevel.AtMostOnce)
                });

發佈消息

發佈消息前需要先構建一個消息物件 MqttApplicationMessage,最直接的方法是使用其實構造函數,傳入主題、內容、QoS 等參數

 var appMsg = new MqttApplicationMessage
                    {
                        Topic = "topic name",
                        Payload = "Message",
                        QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce,
                        Retain = false
                    };
 mqttClient.PublishAsync(appMsg);

參考資料

MQTTnet
MQTT Essentials

猜你喜欢

转载自blog.csdn.net/weixin_43391499/article/details/86154044