2014年3月13日

MQTT(六)UNSUBSCRIBE Message And PINGREQ Message

前言:

上一篇提到用來訂閱主題的SUBSCRIBE Message,接著最後要介紹的兩個訊息,分別為取消訂閱用的UNSUBSCRIBE Message以及用來與Server維持連線的PINGREQ Message。

UNSUBSCRIBE Message

UNSUBSCRIBE Message為client發送給server,用來取消訂閱主題。

Fixed Header:

bit 7 6 5 4 3 2 1 0
byte 1 Message Type(10) DUP flag QoS level RETAIN
1 0 1 0 0 0 1 x
byte 2 Remaining Length

上面為UNSUBSCRIBE Message裡面的fixed header,以下依依介紹它們的作用。

  • Message Type:每種類型的Message都要用到,要根據想用的訊息類型填上相對應的值,值可以參考先前貼的文章MQTT(二)Message Type and Flows。這邊由於是SUBSCRIBE Message的關係,因此會填上1010。

  • DUP flag:標記此訊息為重複(duplicate)的訊息,會用在PUBLISH、PUBREL、SUBSCRIBE、UNSUBSCRIBE上。當client或是server要重新傳送上述訊息時,則要將此flag設為1。此flag會適用於QoS大於0的訊息。

    此flag 只能當成一種提示,表示此則訊息可能在之前有收過了,不應該拿它來當成訊息重複的檢查flag。

  • QoS level:UNSUBSCRIBE Message使用QoS level 1來回應(acknowledge)不同的取消訂閱主題請求。

  • RETAIN:沒有使用到。

  • Remaining Length:此欄位記錄當前的Message,它的Variable header和Payload總共的長度為何,此欄位不一定就是1 byte,它是可變得,最多到4 byte。

接著讓我們繼續往下看,再來是第二個Herader,也就是Variable Header。

Variable Header:

由於UNSUBSCRIBE Message QoS level為1,因此其variable header會包含Message ID,用來確保訊息能夠正確傳送。

下面為SUBSCRIBE Message,variable header欄位範例:

Field Value
Message ID 10

Payload:

UNSUBSCRIBE Message的payload會包含一個主題名稱列表,代表該Client想要取消訂閱的主題。下表爲其payload範例,代表該Client想要取消訂閱兩個主題"a/b"、"c/d":

Topic name "a/b"
Topic name "c/d"

Response:

取消註冊成功,Server會回應一個UNSUBACK Message給client。


看完UNSUBACK Message的介紹之後,緊接著要介紹PINGREQ Message。

PINGREQ Message

PINGREQ Message為client發送給server,用來詢問Server是否還活著。Server收到來自Client的PINGREQ Message之後,會將該位Client的Keep Alive timer歸零重新計算,否則當Keep Alive timer時間到了,則Server會視此Client爲斷線狀態,Server將會關閉TCP socket連線(詳情可參考MQTT(三)CONNECT Message#Keep Alive timer)。因此這訊息反過來說,也算是Client用來回報自己狀況的給Server的訊息。

Fixed Header:

bit 7 6 5 4 3 2 1 0
byte 1 Message Type(12) DUP flag QoS level RETAIN
1 1 0 0 x x x x
byte 2 Remaining Length
0 0 0 0 0 0 0 0

上面為PINGREQ Message裡面的fixed header,以下依依介紹它們的作用。

  • Message Type:每種類型的Message都要用到,要根據想用的訊息類型填上相對應的值,值可以參考先前貼的文章MQTT(二)Message Type and Flows。這邊由於是PINGREQ Message的關係,因此會填上1100。

  • DUP flag:標記此訊息為重複(duplicate)的訊息,PINGREQ Message不會用到此欄位。

  • QoS level:定義該則訊息的QoS level為何,PINGREQ Message不會用到此欄位。

  • RETAIN:沒有使用到。

  • Remaining Length:此欄位記錄當前的Message,它的Variable header和Payload總共的長度為何,PINGREQ Message沒有Variable header,也沒有Payload,因此該欄位爲00000000。

由上面的Fixed header可得知,在MQTT的規範裡,PINGREQ Message是非常輕量化的,只有2 byte而已,因此PINGREQ Message非常適合用來作為機器間互相了解彼此間狀態的訊息。

Response:

Server收到PINGREQ Message,會回應一個PINGRES Message給client,告訴Client它還活著,PINGRES Message跟PINGREQ一樣,也是2 byte而已。

小結

本篇介紹了MQTT的UNSUBSCRIBE Message和PINGREQ Message。

UNSUBSCRIBE此訊息用於取消訂閱主題上,它需要注意的地方在於它可以一次同時取消多個主題。而另外介紹的PINGREQ訊息,此訊息可以讓Client運用最小的頻寬耗損,去告知Server它的狀態,Server也可以反過來利用此訊息得知Client的狀況,避免彼此間裝置上的資源造成不必要的消耗。

參考:

MQTT V3.1 Protocol Specification