項目中用到了MQTT,由於MQTT中支持QoS,服務質量保證,在阿里面試的時候,問到如何設計QoS,一時糊塗,沒有完全回答出來。
特點
MQTT - MQ Telemetry Transport
- 輕量級的 machine-to-machine 通信協議。
- publish/subscribe模式。
- 基於TCP/IP。
- 支持QoS。
- 適合於低帶寬、不可靠連接、嵌入式設備、CPU內存資源緊張。
- 是一種比較不錯的Android消息推送方案。
- FacebookMessenger采用了MQTT。
- MQTT有可能成為物聯網的重要協議。
消息體


MessageType


CONNECT
TCP連接建立完畢后,Client向Server發出一個Request。
如果一段時間內接收不到Server的Response,則關閉socket,重新建立一個session連接。
如果一個ClientID已經與服務器連接,則持有同樣ClientID的舊有連接必須由服務器關閉后,新建立才能建立。
CONNACK
Server發出Response響應。
0x00 Connection Accepted
0x01 Connection Refused: unacceptable protocol version
0x02 Connection Refused: identifier rejected
0x03 Connection Refused: server unavailable
0x04 Connection Refused: bad user name or password
0x05 Connection Refused: not authorized
0x01 Connection Refused: unacceptable protocol version
0x02 Connection Refused: identifier rejected
0x03 Connection Refused: server unavailable
0x04 Connection Refused: bad user name or password
0x05 Connection Refused: not authorized
PUBLISH 發布消息
Client/Servier均可以進行PUBLISH。
publish message 應該包含一個TopicName(Subject/Channel),即訂閱關鍵詞。
關於Topic通配符
/:用來表示層次,比如a/b,a/b/c。
#:表示匹配>=0個層次,比如a/#就匹配a/,a/b,a/b/c。
單獨的一個#表示匹配所有。
不允許 a#和a/#/c。
+:表示匹配一個層次,例如a/+匹配a/b,a/c,不匹配a/b/c。
單獨的一個+是允許的,a+不允許,a/+/b不允許
PUBACK 發布消息后的確認
QoS=1時,Server向Client發布該確認(Client收到確認后刪除),訂閱者向Server發布確認。
PUBREC / PUBREL / PUBCOMP
QoS=2時
1. Server->Client發布PUBREC(已收到);
2. Client->Server發布PUBREL(已釋放);
3. Server->Client發布PUBCOMP(已完成),Client刪除msg;
訂閱者也會向Server發布類似過程確認。
PINGREQ / PINGRES 心跳
Client有責任發送KeepAliveTime時長告訴給Server。在一個時長內,發送PINGREQ,Server發送PINGRES確認。
Server在1.5個時長內未收到PINGREQ,就斷開連接。
Client在1個時長內未收到PINGRES,斷開連接。
一般來說,時長設置為幾個分鍾。最大18hours,0表示一直未斷開。
QoS


QoS=0:最多一次,有可能重復或丟失。
QoS=1:至少一次,有可能重復。
Client[Qos=1,DUP=0/*重復次數*/,MessageId=x] --->PUBLISH--> Server收到后,存儲Message,發布,刪除,向Client回發PUBACK
Client收到PUBACK后,刪除Message;如果未收到PUBACK,設置DUP++,重新發送,Server端重新發布,所以有可能重復發送消息。
QoS=2:只有一次,確保消息只到達一次(用於比較嚴格的計費系統)。