MQTT-基於發布/訂閱模式的輕量級通訊協議

2023.12.07

MQTT-基於發布/訂閱模式的輕量級通訊協議

MQTT(Message Queuing Telemetry Transport)是一種輕量級的、基於發布/訂閱模式的通訊協議,常用於物聯網設備之間的通訊。

MQTT介紹

MQTT(Message Queuing Telemetry Transport)是一種輕量級的、基於發布/訂閱模式的通訊協議,常用於物聯網設備之間的通訊。它具有以下特點:

  • 簡單:MQTT協定設計簡潔,易於實現和部署。
  • 輕量級:協定頭部資訊小,適合在頻寬有限的網路環境中使用。
  • 發布/訂閱模式:支援發布者將訊息發佈到特定的主題,訂閱者可以選擇性地訂閱感興趣的主題,從而實現訊息的分發和接收。
  • 可靠性:支援三種服務品質等級(QoS),包括最多一次、至少一次和恰好一次的訊息傳遞保證。

MQTT協定的訊息格式如下:

[

固定頭部可變頭部有效載荷固定長度可變長度長度可變

]

其中,固定頭部包含控制封包類型、標誌位元和剩餘長度欄位;可變頭部包含協定名稱、協定版本、連接標誌位元等資訊;有效載荷包含實際的訊息內容。

MQTT協定適合在資源受限的設備和網路環境中進行可靠的通訊。

應用場景

  1. 物聯網設備通訊:MQTT可用於連接和通訊各種物聯網設備,包括感測器、執行器、嵌入式設備等,實現設備之間的資料交換和控制。例如,感測器節點可以透過MQTT協定將資料傳送到雲端伺服器,或者設備之間可以透過MQTT進行即時通訊。
  2. 遠端監控與控制:MQTT可用於遠端監控和控制系統,例如遠端監控工廠設備、智慧家庭設備、農業自動化系統等。
  3. 即時數據傳輸:MQTT支援發布/訂閱模式,可用於即時傳輸數據,例如氣象數據、交通資訊、股票行情等。
  4. 行動應用程式通知:MQTT可用於向行動應用程式發送即時通知,例如社群媒體更新、新聞提醒、即時訊息等。
  5. 資源受限的環境:由於MQTT協定的輕量級特性,它適合在資源受限的環境中使用,例如嵌入式系統、感測器網路和低頻寬網路環境。

MQTT適用於需要輕量級、可靠、即時通訊的各種物聯網和即時資料傳輸場景。

協議說明

MQTT控制封包格式

  1. 「固定報頭(Fixed Header)」:包含封包類型和標誌位。
  2. 「可變標頭(Variable Header)」:根據封包類型不同而不同,包含一些額外的資訊。
  3. 「有效載荷(Payload)」:包含實際的數據內容。

MQTT資料包類型:

  1. “CONNECT”:客戶端連接到伺服器時發送的資料包類型。
  2. “CONNACK”:伺服器對客戶端連線請求的回應資料包類型。
  3. “PUBLISH”:用於發布訊息的資料包類型。
  4. “PUBACK”:對PUBLISH訊息的確認資料包類型。
  5. 「PUBREC、PUBREL、PUBCOMP」:用於發布訊息的QoS等級2的封包類型。
  6. “SUBSCRIBE”:訂閱主題的資料包類型。
  7. “SUBACK”:對訂閱請求的確認資料包類型。
  8. “UNSUBSCRIBE”:取消訂閱主題的資料包類型。
  9. “UNSUBACK”:對取消訂閱請求的確認資料包類型。
  10. “PINGREQ、PINGRESP”:用於保持連接的資料包類型。
  11. “DISCONNECT”:客戶端斷開連線時發送的資料包類型。

每種資料包類型都有特定的格式和用途,用於在MQTT協定中進行通訊和訊息傳遞。

MQTT報文標誌位:

  1. 「保留位元(Retain)」:指示伺服器是否應保留訊息。
  2. 「QoS等級(QoS Level)」:指定訊息傳遞的品質。
  3. 「主題訂閱識別(Topic Subscription Identifier)」:指示是否使用主題訂閱識別碼。

一個PUBLISH報文的格式如下:

| 固定报头 | 可变报头 | 有效载荷 |
  • 1.

其中,固定報頭包含封包類型和標誌位,可變標頭包含主題名和封包標識符,有效載荷包含實際的訊息內容。

MQTT使用

導入依賴:

repositories {
    maven {
        url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
    }
}


dependencies {
    compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
    compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

建立客戶端並發布訊息(服務端需搭建MQTT服務):

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

public class MqttJavaExample {
    public static void main(String[] args) {
        String broker = "tcp://iot.eclipse.org:1883";
        String clientId = "JavaExample";
        try {
            MqttClient client = new MqttClient(broker, clientId);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);
            System.out.println("Connecting to broker: " + broker);
            client.connect(connOpts);
            System.out.println("Connected");
            String topic = "iot/topic";
            String content = "Hello, MQTT!";
            int qos = 2;
            MqttMessage message = new MqttMessage(content.getBytes());
            message.setQos(qos);
            System.out.println("Publishing message: " + content);
            client.publish(topic, message);
            System.out.println("Message published");
            client.disconnect();
            System.out.println("Disconnected");
            System.exit(0);
        } catch (MqttException me) {
            System.out.println("reason " + me.getReasonCode());
            System.out.println("msg " + me.getMessage());
            System.out.println("loc " + me.getLocalizedMessage());
            System.out.println("cause " + me.getCause());
            System.out.println("excep " + me);
            me.printStackTrace();
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.

這是一個簡單的使用Eclipse Paho MQTT Java 用戶端程式庫的範例。

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

public class MqttClientExample {

    public static void main(String[] args) {
        String broker = "tcp://iot.eclipse.org:1883";
        String clientId = "JavaSample";
        MemoryPersistence persistence = new MemoryPersistence();

        try {
            MqttClient client = new MqttClient(broker, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);

            System.out.println("Connecting to broker: " + broker);
            client.connect(connOpts);
            System.out.println("Connected");

            String topic = "iot/topic";
            int qos = 2;
            client.subscribe(topic, qos);
            System.out.println("Subscribed to topic: " + topic);

            String content = "Hello, MQTT!";
            MqttMessage message = new MqttMessage(content.getBytes());
            message.setQos(qos);
            client.publish(topic, message);
            System.out.println("Message published");

            client.disconnect();
            System.out.println("Disconnected");
            System.exit(0);
        } catch (MqttException me) {
            System.out.println("reason " + me.getReasonCode());
            System.out.println("msg " + me.getMessage());
            System.out.println("loc " + me.getLocalizedMessage());
            System.out.println("cause " + me.getCause());
            System.out.println("excep " + me);
            me.printStackTrace();
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.

這是一個簡單的使用Eclipse Paho MQTT Java 用戶端的範例。在這個範例中,我們建立了一個MQTT 用戶端並連接到指定的MQTT 代理,然後訂閱了一個主題並發布了一條訊息。

MQTT優缺點

優點

  1. 「輕量級協議」:MQTT是一種輕量級的發布/訂閱訊息傳輸協議,適用於受限的網路環境和設備。
  2. 「低頻寬消耗」:由於其精簡的協定頭和二進位訊息格式,MQTT在傳輸過程中消耗的頻寬較低。
  3. 「可靠性」:MQTT支援三種層級的服務品質(QoS),可以根據需求選擇適當的層級來確保訊息的可靠傳輸。
  4. 「靈活性」:MQTT支援多種場景下的訊息傳輸,包括裝置與雲端的通訊、行動應用通知推播等。
  5. 「易於整合」:MQTT協定已經得到廣泛支持,有許多開源的客戶端和伺服器實現,易於整合到各種應用中。

缺點

  1. 「安全性」:MQTT本身並未提供加密功能,需要透過TLS/SSL等方式來確保通訊的安全性。
  2. 「複雜性」:在某些特定場景下,如需要實現高階的訊息佇列功能或大規模部署時,可能需要複雜的配置和管理。
  3. 「不適用於大數據傳輸」:由於其輕量級的特性,MQTT並不適合用於大規模資料的傳輸,適合傳輸小型的控制資訊和感測器資料。
  4. 「需要穩定的網路連線」:由於其基於TCP的特性,MQTT需要穩定的網路連線來確保訊息的可靠傳輸,不適合在網路不穩定的環境中使用。