MQTT教學(五):「保留」發布訊息以及QoS品質設定

MQTTLens的訊息發布欄位,包含QoS(品質)與Retained(保留)選項。

MQTTLens訊息發布欄位設定

發布訊息時,若Retained(保留)訊息選項為true(勾選),MQTT代理人將保存此主題訊息。其後如有新的訂閱者,或者之前斷線的訂閱者重新連線,都能收到最新一則保留訊息(但並非全部訊息喔~)。

QoS(品質)設定

QoS代表發布者與代理人,或者代理人與訂閱者之間的傳輸品質。MQTT定義了0, 1和2三個層級的品質設定(實際支援情況依伺服器軟體而定,Mosquitto伺服器全都支援):

  • 0:最多傳送一次(at most once)
  • 1:至少傳送一次(at least once)
  • 2:確實傳送一次(exactly once)

用寄信來比喻,QoS 0就像寄平信,不保證訊息會送達

MQTT QoS 0品質訊息傳送流程

補充說明,MQTT裝置之間的訊息傳遞基於TCP/IP,在正常連線狀態下,TCP能確保訊息封包都能抵達目的地。在網路階層架構中,「MQTT程式」屬於應用層,它產生的訊息交給下一層(TCP)處理,但MQTT程式並不清楚最底層的網路是否壅塞甚至斷線,所以才說,MQTT不保證能交付訊息。

QoS 1品質設定則像寄送掛號信;收訊者(如:代理人)收到訊息之後,會回應PUBACK訊息(publish acknowledgement,發布確認)給發布者,確認有收到訊息。在「品質」設定為1或2的情況下,MQTT訊息檔頭後面會夾帶一個稱為packetId(封包ID)的識別碼,收訊者回應的PUBACK訊息也會傳回相同的識別碼提供發布者確認。

MQTT QoS 1品質訊息傳送流程

假如一段時間過後,發布者沒有收到PUBACK回應,它會認定訊息沒有送達,因而重新傳送一次訊息。然而,如果代理人有收到訊息,但是在它傳送回應時,發布者因連線故障而漏接回應。發布者會誤以為對方沒收到訊息而再次傳送,導致訂閱者重複收到相同訊息。

MQTT QoS 1重複發送訊息

最後是QoS 2設定。在此設定模式之下,當收訊者收到訊息時,它將回覆PUBREC(publish received,已收到發布訊息),並且暫存訊息的「封包識別碼」,以防重複處理相同的訊息。當發布者收到PUBREC回應時,將傳送PUBREL(publish release,釋放發布訊息)給代理人,代理人會先把訊息傳送給訂閱者,然後回應PUBCOMP(publish complete,發布完成)並刪除之前暫存的訊息。

MQTT QoS 2品質訊息傳送流程

上圖以「發布者」和「代理人」之間的連線示範;假如「代理人」和「訂閱者」之間的傳送品質設定為1或2,且Clean Session(清除會談,參閱下文)設定為false,而「代理人」在送出訊息之後,沒有收到回應,它將儲存訊息,直到用戶端重新連線,代理人將再次發送這些訊息。

如果佈署的物聯網裝置採用的網路很穩定(如:有線網路),或者在感測器頻繁地發送數據,即使遺漏少數樣本數據也無妨的情況下,只需採用QoS 0設定。

假若你的應用場合需要確實接收每一則訊息,而且你的用戶端程式可以過濾(或者不在乎)重複的訊息,那麼QoS 1設定已足敷使用,因為它不像QoS 2那樣佔用較多網路、處理器資源和傳輸時間(某些網路連線計費是以byte為單位)。

延伸閱讀

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *