項目中用到了MQTT,因爲MQTT中支持QoS,服務質量保證,在阿里面試的時候,問到如何設計QoS,一時糊塗,沒有徹底回答出來。html
特色web
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
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:只有一次,確保消息只到達一次(用於比較嚴格的計費系統)。
Clean Session
若是爲false(flag=0),Client斷開鏈接後,Server應該保存Client的訂閱信息。
若是爲true(flag=1),表示Server應該馬上丟棄任何會話狀態信息。
Refs