MQTT-基於發布/訂閱模式的輕量級通訊協議
2023.12.07
MQTT-基於發布/訂閱模式的輕量級通訊協議
MQTT(Message Queuing Telemetry Transport)是一種輕量級的、基於發布/訂閱模式的通訊協議,常用於物聯網設備之間的通訊。
MQTT介紹
MQTT(Message Queuing Telemetry Transport)是一種輕量級的、基於發布/訂閱模式的通訊協議,常用於物聯網設備之間的通訊。它具有以下特點:
- 簡單:MQTT協定設計簡潔,易於實現和部署。
- 輕量級:協定頭部資訊小,適合在頻寬有限的網路環境中使用。
- 發布/訂閱模式:支援發布者將訊息發佈到特定的主題,訂閱者可以選擇性地訂閱感興趣的主題,從而實現訊息的分發和接收。
- 可靠性:支援三種服務品質等級(QoS),包括最多一次、至少一次和恰好一次的訊息傳遞保證。
MQTT協定的訊息格式如下:
[
固定頭部可變頭部有效載荷固定長度可變長度長度可變
]
其中,固定頭部包含控制封包類型、標誌位元和剩餘長度欄位;可變頭部包含協定名稱、協定版本、連接標誌位元等資訊;有效載荷包含實際的訊息內容。
MQTT協定適合在資源受限的設備和網路環境中進行可靠的通訊。
應用場景
- 物聯網設備通訊:MQTT可用於連接和通訊各種物聯網設備,包括感測器、執行器、嵌入式設備等,實現設備之間的資料交換和控制。例如,感測器節點可以透過MQTT協定將資料傳送到雲端伺服器,或者設備之間可以透過MQTT進行即時通訊。
- 遠端監控與控制:MQTT可用於遠端監控和控制系統,例如遠端監控工廠設備、智慧家庭設備、農業自動化系統等。
- 即時數據傳輸:MQTT支援發布/訂閱模式,可用於即時傳輸數據,例如氣象數據、交通資訊、股票行情等。
- 行動應用程式通知:MQTT可用於向行動應用程式發送即時通知,例如社群媒體更新、新聞提醒、即時訊息等。
- 資源受限的環境:由於MQTT協定的輕量級特性,它適合在資源受限的環境中使用,例如嵌入式系統、感測器網路和低頻寬網路環境。
MQTT適用於需要輕量級、可靠、即時通訊的各種物聯網和即時資料傳輸場景。
協議說明
MQTT控制封包格式
- 「固定報頭(Fixed Header)」:包含封包類型和標誌位。
- 「可變標頭(Variable Header)」:根據封包類型不同而不同,包含一些額外的資訊。
- 「有效載荷(Payload)」:包含實際的數據內容。
MQTT資料包類型:
- “CONNECT”:客戶端連接到伺服器時發送的資料包類型。
- “CONNACK”:伺服器對客戶端連線請求的回應資料包類型。
- “PUBLISH”:用於發布訊息的資料包類型。
- “PUBACK”:對PUBLISH訊息的確認資料包類型。
- 「PUBREC、PUBREL、PUBCOMP」:用於發布訊息的QoS等級2的封包類型。
- “SUBSCRIBE”:訂閱主題的資料包類型。
- “SUBACK”:對訂閱請求的確認資料包類型。
- “UNSUBSCRIBE”:取消訂閱主題的資料包類型。
- “UNSUBACK”:對取消訂閱請求的確認資料包類型。
- “PINGREQ、PINGRESP”:用於保持連接的資料包類型。
- “DISCONNECT”:客戶端斷開連線時發送的資料包類型。
每種資料包類型都有特定的格式和用途,用於在MQTT協定中進行通訊和訊息傳遞。
MQTT報文標誌位:
- 「保留位元(Retain)」:指示伺服器是否應保留訊息。
- 「QoS等級(QoS Level)」:指定訊息傳遞的品質。
- 「主題訂閱識別(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優缺點
優點
- 「輕量級協議」:MQTT是一種輕量級的發布/訂閱訊息傳輸協議,適用於受限的網路環境和設備。
- 「低頻寬消耗」:由於其精簡的協定頭和二進位訊息格式,MQTT在傳輸過程中消耗的頻寬較低。
- 「可靠性」:MQTT支援三種層級的服務品質(QoS),可以根據需求選擇適當的層級來確保訊息的可靠傳輸。
- 「靈活性」:MQTT支援多種場景下的訊息傳輸,包括裝置與雲端的通訊、行動應用通知推播等。
- 「易於整合」:MQTT協定已經得到廣泛支持,有許多開源的客戶端和伺服器實現,易於整合到各種應用中。
缺點
- 「安全性」:MQTT本身並未提供加密功能,需要透過TLS/SSL等方式來確保通訊的安全性。
- 「複雜性」:在某些特定場景下,如需要實現高階的訊息佇列功能或大規模部署時,可能需要複雜的配置和管理。
- 「不適用於大數據傳輸」:由於其輕量級的特性,MQTT並不適合用於大規模資料的傳輸,適合傳輸小型的控制資訊和感測器資料。
- 「需要穩定的網路連線」:由於其基於TCP的特性,MQTT需要穩定的網路連線來確保訊息的可靠傳輸,不適合在網路不穩定的環境中使用。