MQTT心跳機制

心跳機制

  Keep Alive指定連接最大空閒時間T,當客戶端檢測到連接空閒時間超過T時,必須向Broker發送心跳報文PINGREQ,Broker收到心跳請求後返回心跳響應PINGRESP。若Broker超過1.5T時間沒收到心跳請求則斷開連接,並且投遞遺囑消息到訂閱方;同樣,若客戶端超過一定時間仍沒收到心跳響應PINGRESP則斷開連接。 
  連接空閒時發送心跳報文可以降低網絡請求,弱化對帶寬的依賴。

Keep Alive設定時機

  創建連接時,在CONNECT報文中指定,單位s。

Client Take-Over

場景:客戶端與Broker連接正常,然後客戶端快速重啓(小於1.5T),再重新連接Broker,在未達到1.5T這段時間內,客戶端與Broker存在兩條連接。 
處理措施: 先斷開之前的連接再建立新的連接。

一、CONNECT(連接)

當客戶端向服務器建議一個TCP/IP端口連接,協議基本會話必須使用一個CONNECT flow建立。 

下面是一個較爲完整的CONNECT消息結構:

說明:
1、Fixed header/固定頭部:
DUP,QoS和RETAIN標誌不能被使用在CONNECT消息中(無效)。 

Remaining Length是可變頭(12字節)的長度和payload的長度。這可以是一個多字節的字段。 

2、Variable header/可變頭部(12字節)
byte1~byte9: 
    協議名稱(MQIsdp)和協議版本(v3)都是固定的。
byte10:Connect Flags
    一個字節表示,除了第1位是保留未使用,其它7位都具有不同含義。業務上很重要,對消息總體流程影響很大,需要牢記。
    bit[1]:Clean Session
        0,表示如果訂閱的客戶機斷線了,要保存爲其要推送的消息(QoS爲1和QoS爲2),若其重新連接時,需將這些消息推送(若客戶端長時間不連接,需設         置一個過期值); 1,斷線服務器即清理相關信息,重新連接上來之後,會再次訂閱。
    bit[2]:Will Flag
        定義了客戶端(沒有主動發送DISCONNECT消息)出現網絡異常導致連接中斷的情況下,服務器需要做的一些措施。
        簡而言之,就是客戶端預先定義好,在自己異常斷開的情況下,所留下的最後遺願(Last Will),也稱之爲遺囑(Testament)。 這個遺囑就是一個由客         戶端預先定義好的主題和對應消息,附加在CONNECT的可變頭部中,在客戶端連接出現異常的情況下,由服務器主動發佈此消息。只有在Will Flag位爲1         時,Will Qos和Will Retain纔會被讀取,此時消息體payload中要出現Will Topic和Will Message具體內容,否則,Will QoS和Will Retain值會被忽略           掉。
    bit[3-4]:Will Qos
        若標識了Will Flag值爲1,那麼Will QoS就會生效,否則會被忽略掉。
        兩位表示,和PUBLISH消息固定頭部的QoS level含義一樣。這裏先略過,到PUBLISH消息再回過頭來看看,會更明白些。
    bit[5]:Will RETAIN
        如果設置Will Flag值爲1,Will Retain就會生效,否則它將被忽略。
        當客戶端意外斷開服務器發佈其Will Message之後,服務器是否應該繼續保存。這個屬性和PUBLISH固定頭部的RETAIN標誌含義一樣,這裏先掠過。
    bit[6-7]:User name 和 password Flag
        用於授權,兩者要麼爲00 , 要麼爲11,否則都是無效。00--表示客戶端可自由連接/訂閱;11--表示連接/訂閱需要授權。
byte11-12:心跳時間(Keep Alive timer)
    以秒爲單位,定義服務器端從客戶端接收消息的最大時間間隔。一般應用服務會在業務層次檢測客戶端網絡是否連接,不是TCP/IP協議層面的心跳機制(比如    開啓SOCKET的SO_KEEPALIVE選項)。 一般來講,在一個心跳間隔內,客戶端發送一個PINGREQ消息到服務器,服務器返回PINGRESP消息,完成一次心跳    交互,繼而等待下一輪。若客戶端沒有收到心跳反饋,會關閉掉TCP/IP端口連接,離線。 16位兩個字節,可看做一個無符號的short類型值。最大值,2^16-    1 = 65535秒 = 18小時。最小值可以爲0,表示客戶端不斷開。一般設爲幾分鐘,比如微信心跳週期爲300秒。
       
3、Payload/消息體
    消息體定義的消息順序(如上表所示),約定俗成,不得更改,否則將可能引起混亂。
    若Will Flag值爲0,那麼在payload中,Client Identifer後面就不會存在Will Topic和Will Message內容。
    若User Name和Password都爲0,意味着Payload/消息體中,找不到User Name和password的值,就算有,也是無效。標誌決定着是否讀取與否。

     Will Message編碼
          Will Message在CONNECT Payload/消息體中,使用UTF-8編碼。假設內容爲“abcd”,大概如下:


    注意:PUBLISH的Payload/消息體中以二進制編碼保存。
    例如:某刻客戶端異常關閉觸發服務器會PUBLISH此消息。那麼服務器會直接把byte3-byte6之間字符取出,保存爲二進制,附加到PUBLISH消息體中,大       概存儲如下:

二、連接異常中斷通知機制
     CONNECT消息一旦設置在可變頭部設置了Will flag標記,那就啓用了Last-Will-And-Testament特性,此特性很贊。也就是說,一旦客戶端出現異常中斷,     便會觸發服務器發佈Will Message消息到Will Topic主題上去,通知Will Topic訂閱者,對方因異常退出。

三、握手(CONNACK)
    接收到CONNECT消息之後,服務器應該返回一個CONNACK消息作爲響應:

1、若客戶端繞過CONNECT消息直接發送其它類型消息,服務器應關閉此非法連接 若客戶端發送CONNECT之後未收到CONNACT,需要關閉當前連接,然後重新連接;

2、相同Client ID客戶端已連接到服務器,先前客戶端必須斷開連接後,服務器才能完成新的客戶端CONNECT連接。客戶端發送無效非法CONNECT消息,服務器需要關閉

    一個完整的CONNACK消息大致如下:

    連接握手返回碼:

    只有0-5目前被使用到,其他值有待日後使用。一般返回值爲0x00,表示連接建立。非法的請求,需要返回相應的數值。
    從上面看出,一個CONNACT,四個字節表示。一個正常的CONNACT消息實際內容可能如下: 0x20 0x02 0x00 0x00

   若是在私有協議中,兩個字節就足夠了。

   很多時候,客戶端和服務器端在沒有消息傳遞時,會一直保持着連接。雖然不能依靠TCP心跳機制(比如SO_KEEPALIVE選項),業務層面定義心跳機制,會 讓連接狀態檢測、控制更爲直觀。

四、PINGREQ

    由客戶端發送到服務器端,證明自己還在一直連接着呢。兩個字節,固定值。

    客戶端會在一個心跳週期內發送一條PINGREQ消息到服務器端。

    心跳頻率在CONNECT可變頭部“Keep Alive timer”中定義時間,單位爲秒,無符號16位short表示。

五、PINGRESP
    服務器收到客戶端的PINGREQ請求之後,會立即響應一個兩個字節固定格式的PINGRESP消息。

    服務器一般若在1.5倍的心跳週期內接收不到客戶端發送的PINGREQ,可考慮關閉客戶端的連接描述符。此時的關閉連接的行爲和接收到客戶端發送DISCONNECT消息的處理行爲一致,但對客戶端的訂閱不會產生影響(不會清除客戶端訂閱數據),這個需要牢記。

    若客戶端發送PINGREQ之後的一個心跳週期內接收不到PINGRESP消息,可考慮關閉TCP/IP套接字連接。

六、DISCONNECT
    客戶端主動發送到服務器端,表明即將關閉TCP/IP連接。此時要求服務器要完整、乾淨的進行斷開處理,不能僅僅類似於關閉連接描述符類似草草處理之。 需要兩個字節,值固定:


服務器要根據先前此客戶端在發送CONNECT消息可變頭部Connect flag中的“Clean session flag”所設置值,再次複習一下:

    1、值爲0,服務器必須在客戶端斷開之後繼續存儲/保持客戶端的訂閱狀態。這些狀態包括:

            存儲訂閱的消息QoS1和QoS2消息

            正在發送消息期間連接丟失導致發送失敗的消息

            以便當客戶端重新連接時以上消息可以被重新傳遞。

    2、值爲1,服務器需要立刻清理連接狀態數據。

有一點需要牢記,服務器在接收到客戶端發送的DISCONNECT消息之後,需要主動關閉TCP/IP連接。
 

 

發佈了189 篇原創文章 · 獲贊 37 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章