C# 完美實現物聯網 MQTT 數據通信

来源:https://www.cnblogs.com/JackyGz/Undeclared/17959221
-Advertisement-
Play Games

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


iamge

前言

MQTT 協議由於其用極少的代碼和有限的帶寬,為連接遠程設備提供實時可靠的消息服務,具有開銷低、占用帶寬低、即時通訊等優點,使其在物聯網、小型設備、移動應用等方面有較廣泛的應用,在工業物聯網中,MQTT也有廣泛的應用。

Step By Step 步驟

  1. 搭建一個 MQTT 伺服器

  2. 創建一個 .Net Framework Console 項目,命名為 MQTTSample

  3. 添加 NuGet 包

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

    註:在添加這兩個包時,會自動添加其它依賴包

  4. 在 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();
    			}
    
    		}
    	}
    }
    
  5. 編譯並運行測試

    1. 打開一個 CMD 命令視窗,姑且稱為 CMD1,定位到 MQTTSample.exe 所有目錄,如

      cd D:\MQTTSample\MQTTSample\bin\Debug
      
    2. 運行以下命令,運行 MQTT 接收訂閱消息客戶端

      MQTTSample.exe subscribe
      

      註:這個時候,還沒有運行 MQTT 發佈消息客戶端MQTT 接收訂閱消息客戶端 還沒有顯示接收的消息

    3. 重新打開一個 CMD 命令視窗,姑且稱為 CMD2,定位到 MQTTSample.exe 所有目錄

    4. 運行以下命令,運行 MQTT 發佈消息客戶端

      MQTTSample.exe publish
      

      註:此時,按照程式設定,MQTT 發佈消息客戶端 每隔 1 秒不斷發佈消息:this is a test message

    5. 此時,CMD1 視窗的 MQTT 接收訂閱消息客戶端 也會不停地顯示其接收的消息:this is a test message

    6. 至此,說明此 "MQTT 通信" 程式的兩個不同客戶端成功利用 MQTT 伺服器進行通信


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近需要讀取和修改華為路由器的配置,使用Java語言開發,通過SSH連接,輸入命令並讀取響應。 1.添加mwiede/jsch依賴 如果使用Maven,可以在pom.xml文件中添加以下依賴: <dependencies> <dependency> <groupId>com.github.mwied ...
  • 1、簡介 小編最近在使用系統的時候,發現儘管應用已經使用了redis緩存提高查詢效率,但是仍然有進一步優化的空間,於是想到了比分散式緩存性能更好的本地緩存,因此對領域內常用的本地緩存進行了一番調研,有早期的Guava緩存、在Guava上進一步傳承的Caffine以及自稱在Java中使用最廣泛的EhC ...
  • 原文鏈接 https://openaigptguide.com/gpt-store-and-chatgpt-team/ OpenAI推出的兩款新產品和服務:GPT Store和ChatGPT Team,提供了許多全新的解決方案和功能,旨在幫助用戶更輕鬆地使用和構建GPT工具,同時也增加了公司的收入來 ...
  • 近期有同事需要提取加密的pdf文件,截取其中的信息,並且重構pdf文件。網上沒有搜到相關的pdf操作,於是咨詢了chatgpt,給出了pypdf2的使用案例。但是時間比較久遠了,很多庫內的調用介面都已經更新了。 於是自行到官方的庫內學習相關介面使用。整理的處理代碼如下: # -*- coding: ...
  • wenmeng庫當前已支持HTTP1.1/HTTP2/WEBSOCKET,在瀏覽器的環境中websocket是必不可缺少的存在,當然有很多原生的服務中用的都是socket,下一章中,我們將實現websocket與tcp的互轉,以便一些tcp的程式可以服務web的服務。 ...
  • 概述:在C和C++中,int fun()和int fun(void)的區別在於函數參數的聲明方式。前者預設允許任意參數,而後者明確表示沒有參數。通過清晰的實例源代碼,詳細解釋了它們在函數聲明和調用中的不同之處。 在C和C++中,int fun()和int fun(void)的區別在於函數的參數聲明方 ...
  • Python中有多線程的支持。Python的threading模塊提供了多線程編程的基本工具。在下麵,我將列舉一些基礎的多線程用法和一些高級用法,並提供相應的源代碼,其中包含中文註釋。 基礎用法: 創建和啟動線程 import threading import time # 定義一個簡單的線程類 c ...
  • Avalonia中有三個主要的控制項類型:用戶控制項(User Control)、模板化控制項(Templated Control)、基本控制項(Basic Control)。創建自定義控制項時選擇適合的控制項類型進行創建,三種控制項類型適用場景如下(參考文檔): UserControl:適合創建Views或Pa ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...