前言:
上一篇提到建立起連線用的CONNECT Message,接著來談談和發佈訊息有關的Message,PUBLISH Message。
PUBLISH Message
PUBLISH Message是發佈訊息時會用到的訊息類型,它會使用在兩個方向:
- client對某個主題(Topic)散佈訊息,此時它會發送PUBLISH Message給Server。
- server收到了client發送給某個主題的訊息,server會把這些訊息已PUBLISH Message的方式發送給訂閱此主題的client。
每個PUBLISH Message都會包含一個topic name,代表此訊息要發送給哪個主題。
Fixed Header:
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
byte 1 | Message Type(3) | DUP flag | QoS level | RETAIN | ||||
0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | |
byte 2 | Remaining Length |
上面為PUBLISH Message裡面的fixed header,以下依依介紹它們的作用。
Message Type:每種類型的Message都要用到,要根據想用的訊息類型填上相對應的值,值可以參考先前貼的文章MQTT(二)Message Type and Flows。這邊由於是PUBLISH Message的關係,因此會填上0011。
DUP flag:標記此訊息為重複(duplicate)的訊息,會用在PUBLISH、PUBREL、SUBSCRIBE、UNSUBSCRIBE上。當client或是server要重新傳送上述訊息時,則要將此flag設為1。此flag會適用於QoS大於0的訊息。
此flag 只能當成一種提示,表示此則訊息可能在之前有收過了,不應該拿它來當成訊息重複的檢查flag。
QoS level:設定此訊息的QoS level,只有在PUBLISH、PUBREL、SUBSCRIBE、UNSUBSCRIBE才會用到。可以參考MQTT(二)Message Type and Flows:PUBLISH flow來得知比較詳細的資訊。
RETAIN:設定訊息是否要保留在server上,此特性只有PUBLISH才會用到。當client發送PUBLISH Message給Server上的某個Topic時,如果將此flag設為1,則Server將此訊息發佈給當前的所以訂閱者後,必須將此訊息保留。
當有一個新的client對此Topic進行訂閱,則Server必須把最後一則Retain flag設為1的訊息傳送給該client。被設為Retain的訊息必須保留直到Server重啟為止。
此機制會適用於訊息與訊息之間會有一段時間的場景,也就是說,訊息的發佈(Publish)可能不是那麼的頻繁,如錯誤回報的系統。它可以讓新的訂閱者馬上知道上次的最新狀況為何。
Remaining Length:此欄位記錄當前的Message,它的Variable header和Payload總共的長度為何,此欄位不一定就是1 byte,它是可變得,最多到4 byte。
接著讓我們繼續往下看,再來是第二個Herader,也就是Variable Header。
Variable Header:
PUBLISH Message的Variable header會包含以下欄位:
Topic name:
一個UTF的編碼字串,它必須是一個明確的主題定義。不能為萬用字元(wildcard characters),關於萬用字元會在後面的篇幅做介紹。這邊只需知道,當訂閱者用萬用字元訂閱到此主題時,此訂閱者收到的PUBLISH訊息裡面的Topic name欄位會是完整的名稱,而不是用萬用字元匹配到的名稱。
Message ID:
Message ID會使用在QoS level 1或是2的下列訊息上面:PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK。
Message ID為16bit無符號的整數,代表特定方向訊息唯一的id,每個client都會維護他們自己的Message ID列表。所以有可能會有一種狀況發生,就是某個client在發佈Message ID為1的訊息給server時,同時收到Server發佈過來Message ID為1的訊息。
Message ID不能為0,它會被視為無效的Message ID。
下面為PUBLISH Message QoS level為1時,variable header欄位範例:
Field | Value |
---|---|
Topic Name: | "a/b" |
Message ID | 10 |
Payload:
PUBLISH Message的payload會包含要發佈的訊息內容。Payload長度為0的訊息是有效的。
Response:
PUBLISH Message的回應會跟QoS level有關係,下表顯示QoS level與預期的回應:
Qos Level | Expected response |
---|---|
Qos 0 | None |
QoS 1 | PUBACK |
QoS 2 | PUBREC |
PUBLISH Message可以是從client發佈給Server,或者是從server發佈給訂閱者。在收到訊息時,根據QoS level會做以下的動作:
QoS 0:
將訊息提供給任何有興趣的訂閱者。
QoS 1:
將訊息記錄到儲存裝置(persistent storage),將它提供給任何有興趣的訂閱者,然後回傳PUBACK給發送端。
QoS 2:
將訊息記錄到儲存裝置,不要馬上將它提供給任何有興趣的訂閱者,先回傳PUBREC給發送端。
可以參考MQTT(二)Message Type and Flows:PUBLISH flow來得知比較詳細的資訊。
小結
本篇介紹了MQTT的PUBLISH Message,PUBLISH Message其實要注意的就是QoS level和Retain這兩個特性,QoS level會影響到訊息的可靠度,而Retain可以讓新的訂閱者在訂閱主題時就能得知此主題最新的狀態。了解這兩個特性會可以幫助整體服務架構的規劃。
另外還需要注意到,一次只能對一個Topic發佈訊息,所以沒辦法做到一次同時對多個Topic發佈訊息。
沒有留言:
張貼留言