MQTT協議實現(一)

MQTT協議實現(一)

11年的時候,記錄寫過一篇文章《採用MQTT協議實現android消息推送》,那個時候,只是爲了實現推送的功能,沒有仔細閱讀過MQTT協議的內容。最近看同事又重新提起這個協議,於是就心血來潮去實現一下。MQTT協議是在tcp協議之上的,是基於TCP/IP的一個應用協議,正好可以驗證一下自己之前整理的基於tcp的RHSocket框架。

MQTT協議簡述

MQTT(Message Queue Telemetry Transport),遙測傳輸協議,提供訂閱/發佈模式,更爲簡約、輕量,易於使用,針對受限環境(帶寬低、網絡延遲高、網絡通信不穩定),對於移動互聯網的場景的消息推送十分有效。

特點如下:

1.使用發佈/訂閱消息模式,提供一對多的消息發佈,接觸應用程序耦合。

2.對負載內容屏蔽的消息傳輸。

3.使用TCP/IP提供網絡連接。

4.有三種消息發佈服務質量:“至多一次”,“至少一次”,“只有一次”

5.傳輸數據小(最小固定長度的頭部是2個字節),協議交換最小化,以降低網絡流量。

具體的協議內容可以從ibm網站學習:http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html

官方下載地址: http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/MQTT_V3.1_Protocol_Specific.pdf

也可以直接閱讀網友的博客:http://www.blogjava.net/yongboy/archive/2014/02/07/409587.html

閱讀了MQTT的協議內容後,會發現它其實和前面RHSocket框架中提到過的自定義協議內容類似,

協議頭(固定頭部fixedheader,可變頭部variableheader)+內容(內容載體payload)。

固定頭部(第一個固定協議字節,可變長度字節)

第一個字節(8位)

固定攜帶了4個數據內容,message type,dup flag,QoS level,retain。

0 1 2 3 4 5 6 7

第0到3位,這4個bit是message type。

第4位,這1個bit是dup flag。

第5和6位,這2個bit是QoS level。

第7位,這1個bit是retain,預留位。


程序定義如下:

/** message type */
typedef NS_ENUM(UInt8, RHMQTTMessageType) {
    RHMQTTMessageTypeConnect = 1,           //client request to connect to server
    RHMQTTMessageTypeConnAck = 2,           //connect acknowledgment
    RHMQTTMessageTypePublish = 3,           //publish message
    RHMQTTMessageTypePubAck = 4,            //publish acknowledgment
    RHMQTTMessageTypePubRec = 5,            //publish received (assured delivery part 1)
    RHMQTTMessageTypePubRel = 6,            //publish release (assured delivery part 2)
    RHMQTTMessageTypePubComp = 7,           //publish complete (assured delivery part 3)
    RHMQTTMessageTypeSubscribe = 8,         //client subscribe request
    RHMQTTMessageTypeSubAck = 9,            //subscribe acknowledgment
    RHMQTTMessageTypeUnsubscribe = 10,      //client unsubscribe request
    RHMQTTMessageTypeUnsubAck = 11,         //unsubscribe acknowledgment
    RHMQTTMessageTypePingReq = 12,          //ping request
    RHMQTTMessageTypePingResp = 13,         //ping response
    RHMQTTMessageTypeDisconnect = 14,       //client is disconnecting
    RHMQTTMessageTypeReserved = 15          //reserved
};

/** QoS(Quality of Service,服務質量) */
typedef NS_ENUM(UInt8, RHMQTTQosLevel) {
    RHMQTTQosLevelAtMostOnce = 0,               //至多一次,發完即丟棄,<=1
    RHMQTTQosLevelAtLeastOnce = 1,              //至少一次,需要確認回覆,>=1
    RHMQTTQosLevelExactlyOnce = 2,              //只有一次,需要確認回覆,=1
    RHMQTTQosLevelReserved = 3                  //待用,保留位置
};


可變長度字節(爲可變頭部和協議內容的長度之和,動態計算獲得,最小爲1個字節0x7F,最大爲4個字節0xFF,0xFF,0xFF,0x7F)

0xff 0xff 0xff 0x7f
如果可變頭部和包體內容的數據長度之和大於127,則可變長度字節數需要加長,從原來的1個字節,變爲可容納的字節數,最大爲4個字節。

至於爲什麼不是0xff,http://www.blogjava.net/yongboy/archive/2014/02/07/409587.html中有說明,是MQTT協議規定所致。

可變頭部

可變頭部,協議中不同的命令,攜帶的數據內容也不同。http://www.blogjava.net/yongboy/archive/2014/02/09/409630.html

後續通過程序實現分別說明。


包體內容

同上。

具體的內容,已經提供了學習連接,我就不拷貝了,哈哈。

閱讀相關的內容後,應該大概瞭解MQTT協議的字段定義了,下一篇我們從MQTT協議的連接入手,來一步步的學習。

相關代碼已經提交到github,https://github.com/zhu410289616/RHMQTTKit



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章