鏈接服務端網絡
客戶端到服務端的第一個報文必須是CONNECT,且只能發送一次,發送的第二個connect報文看成違規處理並斷開鏈接。編碼
有效載荷包含一個或者多個編碼的字段。包括客戶端的惟一標識符,Will主題,Will消息,用戶名和密碼。spa
除了標識外,其餘字段都是可選的,基於標誌位決定可變報頭中是否須要包含這些字段。3d
固定報頭server
報頭長度:2 Bytesblog
一、報文類型:1 CONNECT字符串
二、標誌位 0 0 0 0:it
三、剩餘長度基礎
等於可變報頭的長度(10)加上有效載荷的長度。cli
可變報頭
在固定CONNECT報文可變報頭包含四個字段,協議名、協議級別、鏈接標誌、保持鏈接:
一、協議名 (Protocol Name)。
若是協議名不正確,server端能夠斷開鏈接。
二、協議級別(Protocol Level)。
使用第7個字節:
客戶端用8位的無符號值表示協議的版本。對於3.1.1,協議級別值是4(04)。
若是發現不支持的協議級別,server必須發送一個0x01的ACK報文響應CONNECT報文,而後斷開鏈接。
三、鏈接標誌(Connect Flags)。
bit 0 : server必須驗證CONNECT的保留標誌位(第0位)是否爲0,若是不爲0必須斷開鏈接。
bit 1:指定了會話狀態的處理方式。用於控制會話狀態的生存時間。
= 0 :server必須基於當前會話的狀態恢復與client的通訊。若是沒有與這個client標識符關聯的會話,server必須建立一個新會話。
在鏈接斷開後,client和server必須保存會話信息。server必須將以後的QoS 1和QoS2級別的消息保存爲會話狀態的一部分,
若是這些消息匹配斷開鏈接時client的任何訂閱。server也能夠保存知足相同條件的QoS 0級別的消息。
= 1:server和client必須丟棄以前的任何會話,並開始一個新的會話。
會話僅持續和網絡鏈接一樣長的時間。與這個會話關聯的狀態數據不能被任何以後的會話重用。
client的會話狀態包括:
server會話狀態包括:
bit 2:遺囑標誌 (Will Flag)
=1:若是鏈接請求被接受了,遺囑消息必須被保存在server端而且與這個網絡鏈接關聯。以後網絡鏈接關閉時,server必須發佈這個遺囑消息。
除非server收到DISCONNECT報文時刪除了這個遺囑消息。
遺囑消息發佈的條件:
以後的鏈接標誌Will QoS 和Will Retain字段會被server用到,同是,有效載荷中必須包含Will Topic 和Will Message字段
一旦被髮布或者server收到了client發送的DISCONNECT,遺囑消息就必須從存儲的會話狀態中移除。
=0:以後的鏈接標誌Will QoS 和Will Retain字段必須爲0,而且有效載荷中不能包含Will Topic 和Will Message字段。
網絡鏈接斷開時,不能發送遺囑消息。
server端應該迅速發佈遺囑消息。在關機或者故障的狀況下,server能夠推遲遺囑消息的發佈直到以後的重啓。
若是發生了這種狀況,在server故障和遺囑消息被髮布之間可能會有一個延遲。
bit 3-4:遺囑QoS Will QoS
這兩位用於指定發佈遺囑消息時使用的服務質量等級。
值由遺囑標誌位決定:
Will Flag = 0:它的值必須設置爲0。
Will Flag = 1:它的值能夠等於0,1,2。
bit 5:遺囑保留 Will Retain
若是遺囑消息被髮布時須要保留,須要指定這一位的值。
若是Will Flag = 0: 它的值爲 0 ,server必須將遺囑消息看成非保留信息發佈。
若是 Will Flag = 1: 它的值爲 1 ,server必須將遺囑消息看成保留信息發佈。
bit 6:密碼標誌 Password Flag
=0:有效載荷中不能包含密碼字段
=1:有效載荷中必須包含密碼字段
若是用戶名標誌爲0,它也必須爲0
bit 7:用戶名標誌 User Name Flag
=0:有效載荷中不能包含用戶名字段
=1:有效載荷中必須包含用戶名字段
四、保持鏈接(Keep Alive)。
使用第九、10字節。
它是一個以秒爲單位的時間間隔,表示爲一個16位的字,它是指在client傳輸完一個控制報文的時刻到發送下一個報文的時刻。
client負責保證報文發送的時間間隔不超過保持鏈接的值。若是沒有任何其餘的報文發送,就必須發送一個PINGREQ報文。
無論保持鏈接的值是多少,client任什麼時候候均可以發送PINGREQ報文,而且使用PINGRESP判斷網絡和server的活動狀態。
= !0 :若是server在1.5倍的時間內沒有收到client的報文,它必須斷開鏈接。
client在發送了PINGREQ後,若是在合理的時間內沒有收到PINGRESP,也應該關閉鏈接。
= 0 :表示關閉鏈接保持的功能。意味着,server不須要由於client不活躍而關閉鏈接。
無論保持值爲多少,任什麼時候候,只要server認爲client是不活躍或無響應的,能夠斷開client鏈接。
可變報頭示例:
有效載荷
CONNECT報文的有效載荷包含一個或多個以長度爲前綴的字段,可變報頭中的標誌決定是否包含這些字段。
若是包含的話,必須按照這個順序出現:client標識符,遺囑主題,遺囑消息,用戶名,密碼。
一、client標識符
server使用client標識符識別client。
鏈接到server的每一個client都有惟一的clientID。
client和server都必須使用clientID識別二者之間的MQTT會話相關的狀態。
clientID必須存在,必須是CONNECT報文有效載荷的第一個字段。
clientID必須是UTF-8編碼字符串。
server必須容許1到23個字節長的UTF-8編碼的clientID,clientID只能包含這些字符:
「0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ」
server能夠容許編碼後超過23個字節的clientID,也能夠容許包含不是上面列表字符的clientID。
若是server拒絕了這個clientID,它必須發送返回碼0x02(表示ID不合格)的CONNACK。
於PUBLISH來講就是消息內容了。
須要有效載荷的控制報文:CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE。 PUBLISH是可選。
二、遺囑主題
若是遺囑標誌爲1,有效載荷的下一個字段是遺囑主題,它必須是UTF-8編碼字符串。
三、遺囑消息
若是遺囑標誌爲1,有效載荷的下一個字段是遺囑消息。遺囑消息定義了將被髮布到遺囑主題的應用消息。
這個字段由一個兩字節長度+有效載荷組成。長度給出了跟在後面的數據的字節數,不包含長度字段自己的兩個字節。
遺囑消息被髮布到遺囑主題時,它的有效載荷只包含這個字段的數據部分,不包含開頭的兩個長度字節。
四、用戶名
若是用戶名標誌爲1:有效載荷的下一個字段就是它,server用於身份驗證和受權。
五、密碼
密碼字段包含一個兩字節的長度字段,長度表示二進制數據的字節數(不包含長度字段自己佔用的兩個字節),後面跟着0-65535字節的二進制數據。
密碼字節:
響應
server檢查CONNECT報文的內容是否是知足任何進一步的限制,能夠執行身份驗證和受權檢查。
若是驗證成功,執行下列步驟:
容許client在發送CONNECT報文後當即發送其它的控制報文;client不須要等待server的CONNACK報文。
若是server拒絕了CONNECT,它不能繼續處理在CONNECT報文以後發送的任何數據。
-----------------------------------------------------------------------------------------------------------------------
CONNACK-確認鏈接請求
server發送給client的第一個報文必須是CONNACK。
若是client在合理的時間內沒有收到CONNACK,client應該關閉鏈接。(合理的時間取決於應用的類型和通訊基礎設施)
固定報頭
報頭格式描述以下:
剩餘長度字段表示可變報頭的長度。對於CONNACK,這個值是2.
可變報頭
可變報頭描述以下:
byte 1 :鏈接確認標誌,1-7位是保留,且必須設置爲0。第0位是當前會話標誌。使server和client在是否有已保存的會話狀態上保持一致。
若是server收到清理會話標誌爲1的鏈接,除了將CONNACK報文中的返回碼設置爲0以外,還必須設置當前會話標誌設爲0。
若是server收到清理會話標誌爲0的鏈接,它的值取決於server是否保存了clientID對應client的會話狀態。若是保存則爲1,不然爲0。
若是server發送了一個包含非零返回碼的CONNACK報文,它必須將當前會話標誌設置爲0。
byte 2 :鏈接返回碼,使用一個字節的無符號值。
若是server收到一個合法的CONNECT報文,可是出於某些緣由沒法處理它,server應該嘗試發送一個包含非零返回碼,再關閉鏈接。
鏈接返回碼:
若是認爲上表中的全部鏈接返回碼都不太適合,那麼server必須關閉鏈接,不須要發送CONNACK報文。
有效載荷
CONNACK沒有載荷