輕量通訊協議 --- MQTT

来源:https://www.cnblogs.com/pandefu/archive/2023/10/10/17755762.html
-Advertisement-
Play Games

介紹 一、MQTT簡介 MQTT(Message Queuing Telemetry Transport) 是一種輕量級的消息傳輸協議,通常用於在物聯網(IoT)和感測器網路中進行通信。它設計用於在低帶寬、不穩定或高延遲的網路環境下傳輸數據,因此非常適用於連接設備之間的通信,尤其是在資源有限的環境中 ...


介紹

一、MQTT簡介

MQTT(Message Queuing Telemetry Transport) 是一種輕量級的消息傳輸協議,通常用於在物聯網(IoT)和感測器網路中進行通信。它設計用於在低帶寬、不穩定或高延遲的網路環境下傳輸數據,因此非常適用於連接設備之間的通信,尤其是在資源有限的環境中。

MQTT 的主要特點包括以下幾點:

  1. 輕量級:MQTT 協議本身非常簡潔,消息頭部占用較少的帶寬,使其在低帶寬網路中運行效率高。

  2. 發佈/訂閱模型:MQTT 使用發佈/訂閱模型,其中客戶端可以訂閱特定的主題(Topic),並接收與該主題相關的消息。發佈者發佈消息到特定主題,然後所有訂閱了該主題的客戶端都將收到該消息。

  3. 可靠性:MQTT 支持三種不同級別的消息傳輸質量,包括最多一次、至少一次和僅一次傳輸,可根據應用需求選擇合適的級別。

  4. 持久會話:MQTT 允許客戶端建立持久會話,以便在連接丟失後重新連接時能夠恢復之前的訂閱和消息傳遞狀態。

  5. QoS(Quality of Service):MQTT 提供不同的 QoS 級別,以確保消息的可靠傳遞。這包括 QoS 0(最多一次傳輸)、QoS 1(至少一次傳輸)和 QoS 2(僅一次傳輸)。

  6. 適應性:MQTT 可以在多種網路協議上運行,包括 TCP/IP、WebSocket 和其他協議。

總之,MQTT 是一種非常適合物聯網和感測器網路的通信協議,因其輕量級和高效的特性而受到廣泛應用。它允許設備之間實時地交換信息,從而支持各種應用,包括智能家居、工業自動化、農業監測等。

二、MQTT 的 QoS 機制

什麼是 QoS 機制?(https://www.emqx.com/zh/blog/introduction-to-mqtt-qos)

很多時候,使用 MQTT 協議的設備都運行在網路受限的環境下,而只依靠底層的 TCP 傳輸協議,並不能完全保證消息的可靠到達。因此,MQTT 提供了 QoS 機制,其核心是設計了多種消息交互機制來提供不同的服務質量,來滿足用戶在各種場景下對消息可靠性的要求。

MQTT 定義了三個 QoS 等級,分別為:

  • QoS 0,最多交付一次。
  • QoS 1,至少交付一次。
  • QoS 2,只交付一次。

其中,使用 QoS 0 可能丟失消息,使用 QoS 1 可以保證收到消息,但消息可能重覆,使用 QoS 2 可以保證消息既不丟失也不重覆。QoS 等級從低到高,不僅意味著消息可靠性的提升,也意味著傳輸複雜程度的提升。

MQTT 的.Net 庫 --- MQTTnet

MQTTnet是一個開源的用於基於MQTT的通信的高性能.NET庫。它提供了一個MQTT客戶端和一個MQTT伺服器(代理),並支持MQTT協議,直到版本5。它與大多數受支持的.NET相容框架版本和CPU體繫結構。

Guthub地址: https://github.com/dotnet/MQTTnet

MQTTnet通過NuGet軟體包管理器交付。可以在這裡找到軟體包:https://www.nuget.org/packages/MQTTnet/

在Visual Studio中,在Package Manager控制臺中使用以下命令手動安裝MQTTnet:

Install-Package MQTTnet

可以通過GitHub上直接查看Demo源碼,或者下載源碼後使用Visual Studio打開,它提供了多個Samples ,每個Samples下有不同的相關方法,有以下幾類:

  • Client_Connection_Samples ---
  • Client_Publish_Samples
  • Client_Subscribe_Samples
  • Logger_Samples
  • Managed_Client_Simple_Samples
  • PackageInspection_Samples
  • RpcClient_Samples
  • Server_ASP_NET_Samples
  • Server_Diagnostics_Samples
  • Server_Intercepting_Samples
  • Server_Retained_Messages_Samples
  • Server_Simple_Samples
  • Server_TLS_Samples

可以下載源碼編譯,運行起來後如下:

image.png

Windows下MQTT消息伺服器的安裝使用

一般,常見的MQTT伺服器軟體有:

  • Mosquitto - 流行的開源MQTT伺服器,但是沒有可視化界面,需要藉助其他工具才可以可視化。

  • EMQX - 強大的開源MQTT伺服器,有可視化界面。

  • HiveMQ - HiveMQ 是一個商業的MQTT伺服器,提供免費的開發者版。

這裡推薦使用EMQX ,它提供了可視化界面,以便更容易地配置、管理和監控MQTT伺服器。

一、下載EMQX

EMQX 官網提供了豐富的文檔,Quick Start 地址:https://www.emqx.io/docs/zh/v5.2/

這裡不建議安裝最新版本,建議降低版本,若安裝最新版本 emqx-5.3.0-windows-amdx64,則會啟動異常,如下所示:

image.png
本次測試使用 emqx-4.4.19-otp24.3.4.6-windows-amd64 版本,如下:

image.png

按照官網教程,進入到安裝目錄/emqx/bin 下,使用以下指令啟動EMQX :

emqx start

二、啟動EMQX 服務

EMQX 常用啟動命令:

命令 描述
start 以守護進程模式啟動 EMQX,運行期間不需要互動式 shell。
console 在 Erlang 或 Elixir 互動式 shell 中啟動 EMQX。用於在開發環境中調試 EMQX,需要與 EMQX 進行交互。
foreground 在前臺模式下啟動 EMQX,不使用互動式 shell。用於在開發環境中啟動 EMQX,但不需要後臺運行。
stop 停止運行中的 EMQX 節點。
ctl 管理和監控 EMQX,執行 emqx ctl help 可以獲取更多詳細信息。

EMQX 常用ctl命令:

命令 描述
status 快速查看當前運行的節點是否運行。
broker 查看當前節點的運行的版本狀態以及運行時長。
observer 可以用於查看運行時狀態。展示一個類似於 linux 的 top 命令的界面。
admins 用於創建、修改、刪除管理員賬戶。
clients 查看和管理客戶端。
topics 查看當前系統中所有訂閱的主題。
subscriptions 查看、增加或者刪除某個客戶端的訂閱。

三、EMQX Dashboard

EMQX Dashboard 是EMQX內置的Web 應用程式,它支持查看運行中的 EMQX 集群的整體連接數,訂閱主題數,消息收發數量和流入流出速率,還包括節點列表和節點信息和一些系統指標信息,同時也可以對一些客戶端連接與訂閱數據進行查看與管理

如果 EMQ 安裝在本機,則使用瀏覽器打開地址 http://127.0.0.1:18083 ,輸入預設用戶名 admin 與預設密碼 public ,登錄進入 Dashboard,如下圖:

image.png

如果忘記了 Dashboard 登錄密碼,可以通過 cli 的 admins 命令進行重置,詳情請參考 命令行 - admins

./bin/emqx ctl admins passwd <Username> <Password>

四、MQTTX Desktop

MQTTX 客戶端是一款跨平臺的 MQTT 桌面客戶端工具。它提供用戶友好的圖形界面,讓用戶可以快速創建、測試 MQTT 連接,併進行MQTT 消息的發佈和訂閱。下載地址:https://mqttx.app/zh/downloads 界面如下圖:

image.png

客戶端代碼編寫

一、準備工作

接下來 我們使用MQTTnet,編寫服務端和客戶端測試一下:

  1. 新建控制台項目,添加MQTTnet庫。

  2. 按照上文中命令啟動EMQX服務

  3. 使用MQTTX Desktop,設置 hostlocalhostprot1883 ,連接服務,如下圖:

image.png

二、代碼編寫

這樣準備工作就做好了,編寫創建發佈客戶端代碼,如下:

public static async Task CreatePublishMQTTClient()
{
    try
    {
        MqttFactory mqttFactory = new MqttFactory();

        var mqttClient = mqttFactory.CreateMqttClient();

        var mqttClientOptions = new MqttClientOptionsBuilder()
            .WithTcpServer("localhost", 1883)
            .WithClientId("Client1")
            .Build();
        var connectResult = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);

        Console.WriteLine("mqttClient connectResult: " + connectResult.ResultCode.ToString());

        while (true)
        {
            var msg = Console.ReadLine();

            string topic = "testtopic/publish";
            string payload = $"{msg} {DateTime.Now:yyyy-MM-dd HH:mm:ss:fff}"; // 消息內容

            var message = new MqttApplicationMessageBuilder()
                .WithTopic(topic)
                .WithPayload(payload)
                .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce) // 設置消息質量
                .WithRetainFlag(false) // 是否保留消息
                .Build();

            await mqttClient.PublishAsync(message, CancellationToken.None);
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

接下來再編寫一個訂閱客戶端代碼:

public static async Task CreateSubscribeMQTTClient()
{
    try
    {
        MqttFactory mqttFactory = new MqttFactory();

        var mqttClient = mqttFactory.CreateMqttClient();

        var mqttClientOptions = new MqttClientOptionsBuilder()
            .WithTcpServer("localhost", 1883)
            .WithClientId("Client1")
            .Build();


        mqttClient.ApplicationMessageReceivedAsync += (e) =>
        {
            Task task = Task.Factory.StartNew(() =>
            {
                var msgArray = e.ApplicationMessage.Payload;
                string result = Encoding.UTF8.GetString(msgArray);
                Console.WriteLine("Received: " + result);
            });

            return task;
        };

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

        Console.WriteLine("mqttClient connectResult: " + connectResult.ResultCode.ToString());

        string topic = "testtopic/subscribe";

        var subscribeOptions = new MqttClientSubscribeOptionsBuilder()
            .WithTopicFilter(topic)
            .Build();

        await mqttClient.SubscribeAsync(subscribeOptions);

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

接下來編寫控制台Main方法,由於MQTT Client方法是非同步的,所以為了避免控制台退出,在調用方法後,增加了一個While 死迴圈保證控制台程式是激活狀態,代碼如下:

static void Main(string[] args)
{
    Console.WriteLine("Choose a creation type: \r\n 1: PublishClient\r\n 2: SubscribeClient");
    var type = Console.ReadLine();
    switch (type)
    {
        case "1":
            _ = CreatePublishMQTTClient();
            break;
        case "2":
            _ = CreateSubscribeMQTTClient();
            break;

    }
    while (true) Thread.Sleep(1000);
}

三、測試

先測試發佈客戶端,在控制台選擇PublishClient,然後等待連接,可以看到連接結果為Success,發送兩條測試消息,可以看到MQTTX Desktop 均收到。

image.png

接下來測試訂閱客戶端,在控制台選擇SubscribeClient,然後等待連接,可以看到連接結果為Success,在MQTTX Desktop 發佈一條消息給訂閱客戶端,可以看到控制台程式中,接收到了測試消息。

image.png

總結

總的來說, 使用C#編寫 MQTT相關代碼的資料還是比較少的,但好在官方文檔足夠詳細,今天試玩一下還是花費不少功夫的。本篇文章作拋磚引玉,淺淺瞭解MQTT這個輕量級的通訊協議,在輔以Demo加深理解,熟悉如何使用,文章末尾也提供諸多參考文章,方便大家借鑒學習。

參考鏈接

MQTTnet Guthub地址: https://github.com/dotnet/MQTTnet

MQTT 入門指南:https://www.emqx.com/zh/mqtt-guide

EMQX 官方文檔:https://www.emqx.io/docs/zh/v5.2/

EMQX 命令行文檔:https://www.emqx.io/docs/zh/v5.2/admin/cli.html

EMQX 配置手冊:https://www.emqx.io/docs/zh/v5.2/configuration/configuration-manual.html

EMQX基礎功能: https://juejin.cn/post/7081629128650129416

MQTTX 客戶端下載:https://mqttx.app/zh/downloads

作者: Niuery Daily

出處: https://www.cnblogs.com/pandefu/>

郵箱: [email protected]

關於作者:.Net Framework,.Net Core ,WindowsForm,WPF ,控制項庫,多線程

本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出 原文鏈接,否則保留追究法律責任的權利。 如有問題, 可郵件咨詢。


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

-Advertisement-
Play Games
更多相關文章
  • 4.1 環境搭建 創建名為spring_mvc_demo2的新module,過程參考3.1節 4.1.1、創建請求控制器 package org.rain.controller; import org.springframework.stereotype.Controller; /** * @aut ...
  • 一、當你擁有一個excel版的介面用例 excel中有用例名稱、url、請求方式和請求參數 二、獲取excel的Url、請求方式和請求參數 # 單獨獲取某個單元格的值,第二行第二列# 第二行數據 row代表行,column代表列# url=sh.cell(row=2,column=2).value# ...
  • 看到一篇 IDEA 快捷鍵的總結,非常全面,分享一下。 本文參考了 IntelliJ IDEA 的官網,列舉了IntelliJ IDEA(Windows 版)的所有快捷鍵。併在此基礎上,為 90% 以上的快捷鍵提供了動圖演示,能夠直觀的看到操作效果。 該快捷鍵共分 16 種,可以方便的按各類查找自己 ...
  • 本文深入探討了Go語言中通道(Channel)的各個方面,從基礎概念到高級應用。文章詳細解析了通道的類型、操作方法以及垃圾回收機制,更進一步通過具體代碼示例展示了通道在數據流處理、任務調度和狀態監控等多個實際應用場景中的作用。本文旨在為讀者提供一個全面而深入的理解,以更有效地使用Go中的通道進行併發 ...
  • 堆疊柱狀圖,是一種用來分解整體、比較各部分的圖。與柱狀圖類似,堆疊柱狀圖常被用於比較不同類別的數值。而且,它的每一類數值內部,又被劃分為多個子類別,這些子類別一般用不同的顏色來指代。 柱狀圖幫助我們觀察“總量”,堆疊柱狀圖則可以同時反映“總量”與“結構”。也就是說,堆疊柱狀圖不僅可以反映總量是多少? ...
  • 目錄XXLJob簡介特性模塊安裝調度中心初始化資料庫配置啟動整合執行器pomymlXxlJobConfig啟動執行器實踐簡單的定時任務在執行器創建任務在調度中心創建執行器在調度中心創建任務帶前置和後置處理的定時任務XxlJob註解詳解創建帶前(後)置處理的任務父子任務父子執行器關聯父子任務執行器側l ...
  • 用Rust手把手編寫一個wmproxy(代理,內網穿透等), HTTP內網穿透支持修改頭信息項目 涉及HTTP1.1 chunked, http2, keep-alive ...
  • Java 21 版本更新中最重要的功能之一就是虛擬線程 (JEP 444)。這些輕量級線程減少了編寫、維護和觀察高吞吐量併發應用程式所需的工作量。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...