全部產品
Search
文件中心

IoT Platform:MQTT協議規範

更新時間:Jun 30, 2024

MQTT是基於TCP/IP協議棧構建的非同步通訊訊息協議,是一種輕量級的發布、訂閱資訊傳輸協議。可以在不可靠的網路環境中進行擴充,適用於裝置硬體儲存空間或網路頻寬有限的情境。使用MQTT協議,訊息寄件者與接收者不受時間和空間的限制。物聯網平台支援裝置使用MQTT協議接入。

支援版本

目前物聯網平台支援MQTT標準協議接入,相容5.0、3.1.1和3.1版本協議,具體的協議請參見MQTT 5.0MQTT 3.1.1MQTT 3.1協議文檔。

重要

若需使用MQTT 5.0協議,請先購買企業版執行個體。

與標準MQTT的區別

  • 支援MQTT的PUB、SUB、PING、PONG、CONNECT、DISCONNECT和UNSUB等報文。

  • 支援clean session。

  • 不支援will、retain msg。

  • 支援QoS 0、QoS 1,不支援QoS 2。

  • 不支援SUB QoS,訊息QoS以發送方(PUB)指定為準。

  • 基於原生的MQTT Topic上支援RRPC同步模式,伺服器可以同步調用裝置並擷取裝置回執結果。

支援的MQTT 5.0特性

MQTT 5.0協議在之前版本基礎上添加了大量全新特性,提高了效能和易用性。更多資訊,請參見Appendix C. Summary of new features in MQTT v5.0MQTT 5.0概述

目前,物聯網平台支援MQTT 5.0的部分新增特性如下。

支援的特性

使用方法

會話到期

  • 裝置建連時設定Clean Start和Session Expiry Interval。

    MqttConnectionOptions options = new MqttConnectionOptions();
    options.setCleanStart(true);
    options.setSessionExpiryInterval(60L);// 單位:秒。
    
    MqttClient mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
    mqttClient.connect(options);
  • 裝置斷連時設定Session Expiry Interval。

    MqttProperties mqttProperties = new MqttProperties();
    mqttProperties.setSessionExpiryInterval(60L);// 單位:秒。
    
    MqttAsyncClient mqttAsyncClient = new MqttAsyncClient(host, clientId, new MemoryPersistence());
    mqttAsyncClient.disconnect(30000, null, null, MqttReturnCode.RETURN_CODE_SUCCESS, mqttProperties);

訊息到期

裝置發送訊息時設定Message Expiry Interval:

IntervalString content = "Hello World";
byte[] payload = content.getBytes();

// 建立訊息。
MqttMessage message = new MqttMessage(payload);
// 設定訊息的服務品質。
message.setQos(1);

MqttProperties mqttProperties = new MqttProperties();

// 設定訊息到期時間。
mqttProperties.setMessageExpiryInterval(600L);

message.setProperties(mqttProperties);

// 發布訊息。
MqttClient mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
mqttClient.publish(topic, message);

訂閱選項

支援設定訂閱選項:

  • QoS:MQTTMessage Service品質等級。支援設定0(QoS 0訊息)和1(QoS 1訊息)。

  • No Local:用戶端是否接收自己發布的訊息。

    對於MQTT 3.1.1版本協議,如果客訂閱了自己發布訊息的Topic,則用戶端會接收到自己發布的訊息。如果使用MQTT 5.0版本協議,此情境下,用戶端在訂閱Topic時,可以設定此選項為true,用戶端將不會接收到自己發布的訊息。

    取值:

    • true:不接收。

    • false:接收。

  • Retain As Publish:服務端向用戶端轉寄訊息時是否保留其中的RETAIN標識。

    取值:

    • true:如果訊息中有RETAIN標識,那麼會保留該標識。如果訊息中沒有RETAIN標識,那麼此選項無效。

    • false:無論訊息中是否有RETAIN標識,都不會保留該標識。

    重要

    Retain As Publish的設定不會影響保留訊息中的RETAIN標識。

  • Retain Handling:指定訂閱建立時服務端是否向用戶端發送保留訊息。

    取值:

    • 0:只要客訂閱成功,服務端就發送保留訊息。

    • 1:客訂閱成功且該訂閱之前不存在,服務端才發送保留訊息。

    • 2:即使客訂閱成功,服務端也不會發送保留訊息。

MqttSubscription mqttSubscription = new MqttSubscription("aaa/bbb");

// 設定訂閱選項QoS。
mqttSubscription.setQos(1);

// 設定訂閱選項No Local。
mqttSubscription.setNoLocal(true);

// 設定訂閱選項Retaion As Published。
mqttSubscription.setRetainAsPublished(true);

// 設定訂閱選項Retain Handling。
mqttSubscription.setRetainHandling(1);

MqttClient mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
mqttClient.subscribe(new MqttSubscription[]{mqttSubscription});

保留訊息

// 建立保留訊息。
String content = "Hello World";
byte[] payload = content.getBytes();
MqttMessage message = new MqttMessage(payload);
// 設定訊息為保留訊息。
message.setRetained(true);

// 發布訊息。
MqttClient mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
mqttClient.publish(topic, message);

遺囑訊息

// 建立遺囑訊息。
String content = "Will Message";
byte[] payload = content.getBytes();
MqttMessage message = new MqttMessage(payload);

MqttConnectionOptions options = new MqttConnectionOptions();
options.setUserName(USERNAME);
options.setPassword(PASSWORD.getBytes());

// 設定遺囑訊息。
options.setWill(topic, message);

// 設定遺囑延遲。
MqttProperties willMessageProperties = new MqttProperties();
willMessageProperties.setWillDelayInterval(60L);
options.setWillMessageProperties(willMessageProperties);

// 建立串連。
MqttClient mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
mqttClient.connect(options);

建連協商

MqttConnectionOptions connOpts = new MqttConnectionOptions();
connOpts.setMaximumPacketSize(1024L);

使用者屬性

MqttProperties properties = new MqttProperties();
List<UserProperty> userPropertys = new ArrayList<>();
userPropertys.add(new UserProperty("key1","value1"));
properties.setUserProperties(userPropertys);

裝置使用MQTT 5.0協議成功接入物聯網平台後,可在雲端作業記錄內容中,查看到上報的UserProperty資料。

重要

最多可添加20個屬性。屬性中Key值不允許以底線(_)開頭,Key和Value最大總長度不超過128個字元。

請求與響應模式

例如:請求方為裝置,接收方為您的商務服務器,您可通過AMQP訂閱或規則流轉後,從訊息的屬性列表中解析出ResponseTopic和CorrelationData,然後調用Pub介面,將響應發送給裝置。

MqttProperties properties = new MqttProperties();
properties.setCorrelationData("requestId12345".getBytes());
properties.setResponseTopic("/" + productKey + "/" + deviceName + "/user/get");
重要
  • 解析出的CorrelationData, 需要通過Base64解碼,才能還原成裝置上報的byte數群組類型資料。

  • ResponseTopic和CorrelationData的最大長度都不能超過128個字元。

錯誤碼增強

更多資訊,請參見錯誤排查

主題別名

不涉及。

共用訂閱

共用訂閱的Topic格式為:$share/${ShareName}/${filter}

  • $share:固定值。共用訂閱Topic必須以$share開頭。

  • ${ShareName}:一個只包含字母、數字和底線(_)的字串。

    訂閱會話通過使用相同的${ShareName}表示共用同一個訂閱,匹配該訂閱的訊息每次只會發布給其中一個會話。

  • ${filter}:非共用訂閱中的主題過濾器,支援字母、數字和底線(_)。

樣本:

MqttConnectionOptions options = new MqttConnectionOptions();
options.setUserName(username);
options.setPassword(password);

MqttClient mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
mqttClient.connect(options);

mqttClient.subscribe("$share/testGroup/user/post", 1);

安全等級

  • TLS直連模式(通道加密):安全層級高。

    重要
    • 支援TLS協議1.0、1.1、1.2和1.3版本,強烈建議您的裝置使用TLS 1.2、1.3加密。因TLS 1.0、1.1版本較老,可能有安全風險。

    • 裝置端Link SDK已配置V1.2和V1.3版本的TLS協議,您無需自行配置。

  • TCP直連模式(通道不加密):不安全,功能即將下線,請勿使用。

    重要

    使用TCP直連模式造成的資料泄露風險和後果,需要由您自行承擔。

Topic規範

Topic定義及分類,請查看什麼是Topic

系統預設通訊類Topic可前往控制台裝置詳情頁查看,功能類Topic可前往具體功能文檔頁查看。

使用限制

裝置身份註冊成功後,針對同一裝置身份資訊,只可選擇一種通訊協定接入物聯網平台,不可多種類型通訊協定同時混用。

使用說明

物聯網平台提供各類裝置端SDK,支援裝置使用MQTT協議接入物聯網平台。擷取SDK方法,請參見使用裝置端SDK接入

裝置基於MQTT協議通過不同方式接入物聯網平台進行通訊的配置說明,請參見: