MQTT 遺囑訊息(Will Message)的使用

emqx發表於2022-01-20

簡介

當客戶端斷開連線時,傳送給相關的訂閱者的遺囑訊息。以下情況下會傳送 Will Message:

服務端發生了I/O 錯誤或者網路失敗;

客戶端在定義的心跳時期失聯;

客戶端在傳送下線包之前關閉網路連線;

服務端在收到下線包之前關閉網路連線。

遺囑訊息一般通過在客戶端 CONNECT 的時候指定。如下所示,在連線的時候通過呼叫 MqttConnectOptions 例項的 setWill 方法來設定。任何訂閱了下面的主題的客戶端都可以收到該遺囑訊息。

//方法1 MqttConnectOptions.setWill(MqttTopic topic, byte[] payload, int qos, boolean retained)

//方法2 MqttConnectOptions.setWill(java.lang.String topic, byte[] payload, int qos, boolean retained)

使用場景

在客戶端 A 進行連線時候,遺囑訊息設定為”offline“,客戶端 B 訂閱這個遺囑主題。 當 A 異常斷開時,客戶端 B 會收到這個”offline“的遺囑訊息,從而知道客戶端 A 離線了。

Connect Flag 報文欄位

MQTT 遺囑訊息(Will Message)的使用

遺囑訊息在客戶端正常呼叫 disconnect 方法之後並不會被髮送。

Will Flag 作用 簡而言之,就是客戶端預先定義好,在自己異常斷開的情況下,所留下的最後遺願(Last Will),也稱之為遺囑(Testament)。這個遺囑就是一個由客戶端預先定義好的主題和對應訊息,附加在CONNECT的可變報文頭部中,在客戶端連線出現異常的情況下,由伺服器主動釋出此訊息。

當Will Flag位為1時,Will QoS和Will Retain才會被讀取,此時訊息體中要出現Will Topic和Will Message具體內容,否則Will QoS和Will Retain值會被忽略掉。

當Will Flag位為0時,則Will Qos和Will Retain無效。

命令列示例

下面是一個Will Message的示例:

1.Sub端clientid=sub預定義遺囑訊息:

mosquitto_sub --will-topic test --will-payload die --will-qos 2 -t topic -i sub -h 192.168.1.1

2.客戶端 clientid=alive 在 192.168.1.1(EMQ伺服器) 訂閱遺囑主題

mosquitto_sub -t test -i alive -q 2 -h 192.168.1.1

3.異常斷開Sub端與Server端(EMQ伺服器)連線,Pub端收到Will Message 。

高階使用場景 這裡介紹一下如何將 Retained 訊息與Will 訊息結合起來進行使用。

客戶端 A 遺囑訊息設定為”offline“,該遺囑主題與一個普通傳送狀態的主題設定成同一個 A/status;

當客戶端 A 連線時,向主題 A/status 傳送 “online” 的 Retained 訊息,其它客戶端訂閱主題 A/status的時候,獲取 Retained 訊息為 “online” ; 當客戶端 A 異常斷開時,系統自動向主題 A/status 傳送”offline“的訊息,其它訂閱了此主題的客戶端會馬上收到”offline“訊息;如果遺囑訊息被設定了 Retained 的話,這時有新的訂閱A/status主題的客戶端上線的時候,獲取到的訊息為“offline”。

相關文章