乘風破浪,遇見最佳跨平臺跨終端框架.Net Core/.Net生態 - 對接MQTT和它的代理們

什麼是MQTT

https://mqtt.org

image

MQTT(Message Queuing Telemetry Transport)是一種輕量級的通信協議,專門用於物聯網(IoT)設備之間的通信。它是基於發佈/訂閱(publish/subscribe)模式的協議,通過中間代理(broker)進行消息的傳輸

MQTT在物聯網應用中被廣泛使用,特別是在傳感器網絡、遠程監控、物聯網平臺等領域。它提供了一種簡單、高效、可靠的方式來實現設備之間的通信和數據傳輸。

基本概念

  • 發佈/訂閱模式:MQTT使用發佈/訂閱模式,其中發佈者(Publisher)將消息發佈到特定的主題(Topic),而訂閱者(Subscriber)可以選擇訂閱感興趣的主題。這種模式可以實現一對多的消息傳遞。

  • 主題(Topic):主題是MQTT中消息的分類標識。發佈者發佈消息到特定的主題上,而訂閱者則訂閱感興趣的主題以接收相關消息。

  • 代理(Broker)代理是MQTT通信的中間服務器,負責接收發布者發送的消息,並將其傳遞給相應的訂閱者。代理還可以處理訂閱和取消訂閱請求,並維護客戶端之間的連接。

服務質量等級(QoS)

服務質量等級(QoS, Quality of Service):MQTT提供了不同的服務質量等級,用於確保消息的可靠性和傳輸效率。

QoS級別包括

  • QoS 0(最多一次):消息最多傳輸一次,不保證消息的可靠性。
  • QoS 1(至少一次):消息至少傳輸一次,確保消息到達代理,但可能會出現重複消息。
  • QoS 2(僅一次):消息僅傳輸一次,確保消息只被傳遞一次,確保最高的可靠性。

特點

  • 輕量級:MQTT被設計爲一種輕量級的協議,具有較小的網絡開銷和資源需求。這使得它非常適合在受限的網絡環境和資源受限的設備上使用。

  • 支持異步通信:MQTT允許發佈者和訂閱者進行異步通信,不需要兩者同時在線。發佈者可以發佈消息,而訂閱者可以在其上線後接收到消息。

和消息隊列的區別

MQTT是一種輕量級的通信協議,專門用於物聯網設備之間的通信。它基於發佈/訂閱模式,通過中間代理(Broker)進行消息的傳輸。MQTT適用於需要實時傳輸數據、低帶寬消耗和資源受限的環境,例如傳感器網絡和物聯網應用。

消息隊列是一種通信模式,用於在分佈式系統中進行異步消息傳遞。它通常基於消息隊列服務(Message Queue Service),提供消息的存儲、轉發和交付等功能。消息隊列可以用於解耦消息的發送者和接收者,實現異步通信、流量控制和削峯填谷等功能。它適用於處理大量消息和高併發的情況,例如應用程序之間的解耦、任務調度和事件驅動架構等。

MQTT和消息隊列之間的一些區別

  • 通信模式:MQTT是基於發佈/訂閱模式的通信協議,允許多個訂閱者訂閱特定主題的消息。消息隊列通常是基於點對點或發佈/訂閱模式的,消息的發送者將消息發送到隊列中,然後接收者從隊列中接收消息。

  • 應用場景:MQTT主要用於物聯網設備之間的實時通信,例如傳感器數據的實時傳輸和設備控制。消息隊列更適用於解耦和異步通信的場景,例如大規模分佈式系統、任務處理和事件驅動架構。

  • 傳輸特點:MQTT是一種輕量級協議,具有較小的網絡開銷和資源需求。它通常用於低帶寬環境和資源受限的設備。消息隊列通常提供持久化、消息確認和重試等特性,以確保消息的可靠性和可用性。

  • 擴展性和性能:MQTT適用於大規模的設備連接,但在處理大量併發連接時性能可能受到限制。消息隊列通常具有良好的擴展性和高吞吐量,能夠處理大量的消息和併發請求。

MQTT適用於物聯網設備之間的實時通信,而消息隊列適用於解耦和異步通信的場景。選擇使用哪種機制取決於具體的應用需求、通信模式和性能要求。在某些情況下,MQTT和消息隊列也可以結合使用,根據實際情況選擇合適的通信方式。

MQTT的代理(Broker)

MQTT協議支持多種不同的代理(broker)實現,官方已有一些推薦,以下是一些常見的MQTT broker及其優缺點:

Mosquitto

https://mosquitto.org

https://test.mosquitto.org

Eclipse Mosquitto是一個開源的(EPL/EDL許可)消息代理,實現了MQTT協議的5.0、3.1.1和3.1版本。Mosquitto是輕量級的,適合在所有設備上使用,從低功率的單板計算機到完整的服務器。

image

  • 優點:Mosquitto是一個開源的、輕量級的MQTT broker,易於安裝和配置。它具有較低的資源消耗,適用於嵌入式設備和資源受限的環境。Mosquitto還提供了可擴展性和安全性的特性。
  • 缺點:在處理大量併發連接時,Mosquitto的性能可能受到限制。

HiveMQ

https://www.hivemq.com

HiveMQ是一個MQTT代理,它從一開始就以最大的可擴展性和企業級的安全性爲目標。它有原生的網絡套接字支持和一個開源的插件SDK來擴展其功能或將其與其他組件集成。

image

  • 優點:HiveMQ是一個功能強大的商業MQTT broker,具有良好的可擴展性和性能。它支持高併發連接和大規模部署,並提供了可靠性和可用性方面的高級功能。HiveMQ還提供了全面的安全特性和集成選項。
  • 缺點:HiveMQ是商業產品,需要付費許可證才能使用其高級功能。

EMQX

https://www.emqx.com/en/products/emqx

EMQX是一個完全開源、高度可擴展、高度可用的分佈式MQTT消息代理,用於物聯網、M2M和移動應用,可以處理數千萬個併發客戶端。
從3.0版本開始,EMQX完全支持MQTT V5.0協議規範,並向後兼容MQTT V3.1和V3.1.1,以及其他通信協議,如MQTT-SN、CoAP、LwM2M、WebSocket和STOMP。EMQX的3.0版本可以在一個集羣上擴展到1000多萬個併發的MQTT連接。

image

  • 優點:EMQ X是一個開源的、高度可擴展的MQTT broker,具有出色的性能和可靠性。它支持海量併發連接和分佈式部署,並提供了高級的安全特性和集羣功能。EMQ X還支持多種協議和插件擴展。
  • 缺點:配置和管理EMQ X可能需要一定的學習成本,對於初學者來說可能有一定的複雜性。

RabbitMQ

https://www.rabbitmq.com

RabbitMQ是一個AMQP消息代理 - 有一個MQTT插件(捆綁在3.x版本以上)。

image

  • 優點:RabbitMQ是一個通用的消息代理,支持多種協議,其中包括MQTT。它具有成熟的可靠性和可用性特性,支持高吞吐量和可擴展性。RabbitMQ還提供了豐富的功能和靈活的路由規則。
  • 缺點:相比於專門爲MQTT設計的代理,RabbitMQ在MQTT方面的性能可能較低

MQTTnet

https://github.com/dotnet/MQTTnet

MQTTnet是一個高性能的.NET庫,用於基於MQTT的通信。它提供了一個MQTT客戶端和一個MQTT服務器(Broker),並支持MQTT協議的第5版。它與大多數支持的.NET框架版本和CPU架構兼容。

image

  • 優點

    • 開源且活躍的社區支持:MQTTnet是一個開源項目,擁有活躍的社區支持。這意味着你可以從社區中獲取更新、修復bug和功能擴展,以及與其他開發者分享經驗和解決方案。

    • 跨平臺支持:MQTTnet是基於C#語言開發的,可以在多個平臺上使用,包括Windows、Linux和.NET Core等。這使得它具有廣泛的應用領域和靈活性。

  • 簡單易用:MQTTnet提供了簡單而直觀的API,使得在.NET平臺上實現MQTT通信變得簡單易用。它提供了連接管理、發佈/訂閱功能以及QoS支持等核心功能。

    • 高度可配置:MQTTnet允許你根據需求進行靈活的配置。你可以設置連接選項、消息保留策略、QoS級別、消息處理回調等,以滿足不同的通信需求。
  • 缺點

    • C#語言限制:由於MQTTnet是基於C#語言的,因此它在某些嵌入式設備或特定平臺上的可用性可能會受到限制。

    • 可能存在性能瓶頸:儘管MQTTnet已經努力優化性能,但在處理大量併發連接或高吞吐量時,仍可能面臨性能瓶頸的挑戰。這需要根據具體應用場景進行測試和優化。

    • 依賴於第三方庫:MQTTnet可能依賴於其他第三方庫,這可能增加項目的複雜性和維護的難度。需要注意對依賴庫的版本控制和更新。

這些僅是一些常見的MQTT broker實現,還有其他許多可選擇的實現,每個實現都有其自己的特點和適用場景。選擇合適的MQTT broker取決於你的具體需求,包括預期的併發連接數、性能要求、可擴展性需求、安全性需求以及預算等因素。

Mosquitto安裝

Windows安裝包

image

image
image
image

安裝之後,它會自動創建一個mosquitto的服務,默認是沒有自動開啓的,我們可以手動打開下。

image

image

這時候這個代理就運行起來了。

Docker運行

https://hub.docker.com/_/eclipse-mosquitto

執行如下命令即可:

docker run -d --name mosquitto --restart unless-stopped -p 1883:1883 -p 9001:9001 eclipse-mosquitto:2.0.15

image

調試MQTT

MQTT.fx

https://softblade.de/en/welcome/

MQTTX

MQTTX是一款開源的跨平臺桌面客戶端,它簡單易用且提供全面的MQTT 5.0功能、特性測試,可運行在macOS, Linux和Windows上。同時,它還提供了命令行及瀏覽器版本,滿足不同場景下的MQTT測試需求。

https://mqttx.app

https://github.com/emqx/MQTTX

https://github.com/emqx/MQTTX/releases

image

image

對接MQTT

通過MQTTnet對接MQTT

Nuget包

https://github.com/dotnet/MQTTnet

https://www.nuget.org/packages/MQTTnet

dotnet add package MQTTnet

連接

連接代碼

var mqttFactory = new MqttFactory();

using (var mqttClient = mqttFactory.CreateMqttClient())
{
    // Use builder classes where possible in this project.
    var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1").Build();

    // This will throw an exception if the server is not available.
    // The result from this message returns additional data which was sent 
    // from the server. Please refer to the MQTT protocol specification for details.
    var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);

    Console.WriteLine("The MQTT client is connected.");

    //response.DumpToConsole();

    // Send a clean disconnect to the server by calling _DisconnectAsync_. Without this the TCP connection
    // gets dropped and the server will handle this as a non clean disconnect (see MQTT spec for details).
    var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder().Build();

    await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None);
}

訂閱

var mqttFactory = new MqttFactory();

using (var mqttClient = mqttFactory.CreateMqttClient())
{
    var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();

    // Setup message handling before connecting so that queued messages
    // are also handled properly. When there is no event handler attached all
    // received messages get lost.
    mqttClient.ApplicationMessageReceivedAsync += e =>
    {
        Console.WriteLine("Received application message.");
        e.DumpToConsole();

        return Task.CompletedTask;
    };

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

    var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
        .WithTopicFilter(
            f =>
            {
                f.WithTopic("mqttnet/samples/topic/2");
            })
        .Build();

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

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

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

發送

var mqttFactory = new MqttFactory();

using (var mqttClient = mqttFactory.CreateMqttClient())
{
    var mqttClientOptions = new MqttClientOptionsBuilder()
        .WithTcpServer("broker.hivemq.com")
        .Build();

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

    var applicationMessage = new MqttApplicationMessageBuilder()
        .WithTopic("samples/temperature/living_room")
        .WithPayload("19.5")
        .Build();

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

    await mqttClient.DisconnectAsync();
    
    Console.WriteLine("MQTT application message is published.");
}

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章