MQTT 協議中的 Keep Alive 。
為什麼需要 Keep Alive
MQTT 協議是承載於 TCP 協議之上的,而 TCP 協議以連線為導向,在連線雙方之間,提供穩定、有序的位元組流功能。 但是,在部分情況下,TCP 可能出現半連線問題。所謂半連線,是指某一方的連線已經斷開或者沒有建立,而另外一方的連線卻依然維持著。在這種情況下,半連線的一方可能會持續不斷地向對端傳送資料,而顯然這些資料永遠到達不了對端。為了避免半連線導致的通訊黑洞,MQTT 協議提供了 Keep Alive 機制,使客戶端和 MQTT 伺服器可以判定當前是否存在半連線問題,從而關閉對應連線。
Keep Alive 的機制流程與使用
啟用
客戶端在建立和 MQTT Broker 的連線時,只要將連線請求協議包內的 Keep Alive 可變頭部欄位設定為非 0 值,就可以在通訊雙方間啟用 Keep Alive 機制。 Keep Alive 為 0~65535 的一個整數,代表客戶端傳送兩次 MQTT 協議包之間的最大間隔時間。
而 Broker 在收到客戶端的連線請求後,會檢查可變頭部中的 Keep Alive 欄位的值,如果有值,則 Broker 將會啟用 Keep Alive 機制。
在 MQTT 5.0 標準中,引入了 Server Keep Alive 的概念,允許 Broker 根據自身的實現等因素,選擇接受客戶端請求中攜帶的 Keep Alive 值,或者是覆蓋這個值。如果 Broker 選擇覆蓋這個值,則需要將新值設定在連線確認包( CONNACK) 的 Server Keep Alive 欄位中,客戶端如果在連線確認包中讀取到了 Server Keep Alive,則需要使用該值,覆蓋自己之前的 Keep Alive的值。
Keep Alive 機制流程
-
客戶端流程
在連線建立後,客戶端需要確保, 自己任意兩次 MQTT 協議包的傳送間隔不超過 Keep Alive 的值,如果客戶端當前處於空閒狀態,沒有可傳送的包,則可以傳送 PINGREQ 協議包。
當客戶端傳送 PINGREQ 協議包後,Broker 必須返回一個 PINGRESP 協議包,如果客戶端在一個可靠 的時間內,沒有收到伺服器的 PINGRESP 協議包,則說明當前存在半連線、或者 Broker 已經下線、或者出現了網路故障,這個時候,客戶端應當關閉當前連線。
-
Broker 流程
在連線建立後,Broker 如果沒有在 Keep Alive 的 1.5 倍時間內,收到來自客戶端的任何包,則會認為和客戶端之間的連線出現了問題,此時 Broker 便會斷開和客戶端的連線。
如果 Broker 收到了來自客戶端的 PINGREQ 協議包,需要回復一個 PINGRESP 協議包進行確認。
-
客戶端接管機制
當 Broker 記憶體在半連線時,如果此時對應的客戶端發起了重連、新的連線,則 Broker 會啟動客戶端接管機制:關閉舊的半連線,然後與客戶端建立新的連線。
這種機制保證了客戶端不會因為 Broker 內的半連線問題,導致無法進行重連。
如何在 EMQX 中使用 Keep Alive
在 EMQX 中,使用者可以透過配置來自定義 Keep Alive 機制的行為,主要配置欄位有:
zone.${zoneName}.server_keepaliveserver_keepalive 型別 預設值 整型 無
如果沒有設定這個值,則 EMQX 會按照客戶端建立連線時的 Keep Alive 的值,來控制 Keep Alive 的行為。
如果設定了這個值,則 Broker 會對該 zone 下面所有的連線,強制啟用 Keep Alive 機制,並且會使用這個值,覆蓋客戶端連線請求中的值。
zone.${zoneName}.keepalive_backoffkeepalive_backoff 型別 預設值 浮點數 0.75
MQTT 協議中要求 Broker 在 1.5 倍 Keep Alive 時間內,如果沒有收到客戶端的任何協議包,則認定客戶端斷開了連線。
而在 EMQX 中,我們引入了退讓係數(keepalive backoff),並將這個係數透過配置暴露出來,方便使用者更靈活的控制 Broker 端的 Keep Alive 行為。
在引入退讓係數後,EMQX 透過下面的公式來計算最大超時時間:
Keepalive * backoff * 2
backoff 預設值為0.75,因此在使用者不修改該配置的情況下,EMQX 的行為完全符合 MQTT 標準。
更多相關內容請參見 EMQX 配置文件。
WebSocket 連線時設定 Keep Alive
EMQX 支援客戶端透過 WebSocket 接入,當客戶端使用 WebSocket 發起連線時,只需要在連線引數中設定上 keepalive 的值即可, 具體見 使用 WebSocket 連線 MQTT 伺服器。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70014415/viewspace-2896535/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MQTT 協議 Keep Alive 詳解MQQT協議
- 關於 Http 協議中的 keep-alive 與 Tcp keep-aliveHTTP協議Keep-AliveTCP
- 關於 HTTP 協議中的 keep-aliveHTTP協議Keep-Alive
- HTTP協議頭部與Keep-Alive模式詳解HTTP協議Keep-Alive模式
- http keep-alive與tcp keep-aliveHTTPKeep-AliveTCP
- Vue中keep-alive元件的理解VueKeep-Alive元件
- MQTT協議(二)MQQT協議
- 車聯網場景中的 MQTT 協議MQQT協議
- 初識MQTT協議MQQT協議
- MQTT協議實踐MQQT協議
- Mqtt協議規範MQQT協議
- vue <keep-alive>VueKeep-Alive
- vue keep-aliveVueKeep-Alive
- MQTT 協議快速體驗MQQT協議
- MQTT 3.1.1協議[翻譯]MQQT協議
- HTTP協議和MQTT協議對比誰更好HTTP協議MQQT
- keep-alive元件使用Keep-Alive元件
- Vue中keep-alive的深入理解和使用VueKeep-Alive
- vue中動態化的按需使用keep-aliveVueKeep-Alive
- vue中keep-alive保持使用過的狀態VueKeep-Alive
- MQTT 協議 -- CONNECT & CONNACKMQQT協議
- 輕量通訊協議 --- MQTT協議MQQT
- 19_MQTT協議介紹MQQT協議
- MQTT工作筆記0001---MQTT協議概述MQQT筆記協議
- node http keep-alive demoHTTPKeep-Alive
- WebSocket 和Keep Alive區別?Web
- ??TCP協議:超時重傳、流量控制、keep-alive和埠號,你真的瞭解嗎?TCP協議Keep-Alive
- vue的keep-alive中使用EventBusVueKeep-Alive
- MQTT協議學習與在Java(Android通用)中的使用MQQT協議JavaAndroid
- MQTT協議 -- 訊息報文格式MQQT協議
- mqtt 協議之 PINGREQ, PINGRESPMQQT協議
- keep-alive:元件級快取Keep-Alive元件快取
- 客戶端禁用Keep-alive, 服務端開啟Keep-alive,會怎麼樣?客戶端Keep-Alive服務端
- MQTT協議 paho.mqtt.golang keepAlive原始碼淺析MQQT協議Golang原始碼
- vue2的keep-alive的總結VueKeep-Alive
- 徹底揭祕keep-alive原理Keep-Alive
- Vue keep-alive實踐總結VueKeep-Alive
- Vue 頁面快取keep-aliveVue快取Keep-Alive