共建Prime的Blazor版:為開源社區註入新活力 Prime組件庫作為一款廣受歡迎的開源組件庫,一直以來都備受開發者們的青睞。然而,隨著技術的不斷發展和更新,原團隊的Blazor版本似乎已經逐漸失去了活力,長時間沒有得到更新和維護。在這樣的背景下,一群熱愛開源、熱衷於Blazor技術的開發者們決 ...
前言
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 伺服器進行通信
-