【太極創(chuàng)客】零基礎(chǔ)入門學(xué)用物聯(lián)網(wǎng) - MQTT篇 2-5 心跳機制

為了幫助您學(xué)習(xí),我們專門為本教程制作了視頻。
↓

在醫(yī)院里,醫(yī)生利用心跳來判斷患者是否還有生命體征。對于MQTT服務(wù)器來說,它要判斷一臺MQTT客戶端是否依然保持連接可以檢查這臺客戶端是不是經(jīng)常發(fā)送消息給服務(wù)端。如果服務(wù)端經(jīng)常收到客戶端的消息,那么沒問題,這個客戶端肯定在線。
但是有些客戶端并不經(jīng)常發(fā)送消息給服務(wù)端。對于這種客戶端,服務(wù)端可以使用類似心跳檢測的方法,來判斷客戶端是否在線。

不過客戶端設(shè)備沒有心臟,自然不會跳動。所以MQTT協(xié)議為它們配上一個類似心臟的機制,這個心臟機制就是讓客戶端在沒有向服務(wù)端發(fā)送信息時,可以定時向服務(wù)端發(fā)送一條消息。這條用于心跳機制的消息也被稱作心跳請求(PINGREQ)。

心跳請求的作用正是用于告知服務(wù)端,當(dāng)前客戶端依然在線。服務(wù)端在收到客戶端的心跳請求后,會回復(fù)一條消息。這條回復(fù)消息被稱作心跳響應(yīng)(PINGRESP)。
由于心跳請求是客戶端定時發(fā)送的,一旦服務(wù)端發(fā)現(xiàn)客戶端停止發(fā)送請求信息,那么服務(wù)端就會知道,這臺客戶端已經(jīng)斷開了連接。
這個心跳機制不僅可以用于服務(wù)端判斷客戶端是否保持連接,也可以用于客戶端判斷自己與服務(wù)端是否保持連接。如果客戶端在發(fā)送心跳請求(PINGREQ)后,沒有收到服務(wù)端的心跳響應(yīng)(PINGRESP),那么客戶端就會認(rèn)為自己與服務(wù)端的連接已經(jīng)被斷開了。
以上是心跳機制(Keep Alive)的簡單介紹,為了更深入的了解心跳機制,我們來看一下一下MQTT客戶端在連接服務(wù)端的過程。請見下圖,客戶端連接服務(wù)端時會像服務(wù)端發(fā)送CONNECT報文。

我剛剛給大家講過,在心跳機制中,客戶端要定時向服務(wù)端發(fā)送心跳請求(PINGREQ)報文。那么客戶端發(fā)送心跳請求的時間間隔是多少呢?
這個心跳時間間隔是我們在開發(fā)客戶端時進(jìn)行設(shè)置的。假如我們使用ESP8266開發(fā)板作為物聯(lián)網(wǎng)客戶端,那么我們在編寫控制程序時,會在程序中對心跳時間間隔進(jìn)行設(shè)置。
設(shè)置好心跳時間間隔后,客戶端就知道多久要發(fā)送一條心跳請求給服務(wù)端。但是這里存在一個問題。光是客戶端知道心跳時間間隔還不夠,服務(wù)端也需要知道客戶端的心跳時間間隔,這樣服務(wù)端才能定時檢查客戶端的心跳請求消息。
因此,在客戶端連接服務(wù)端時,會將心跳時間間隔信息放入CONNECT報文。也就是上圖中最后一行的信息keepAlive。這個keepAlive正是用于告知服務(wù)端心跳時間間隔的。
以上示例圖中我們看到keepAlive數(shù)值為60。這就意味著,客戶端的心跳間隔時間是60秒。
接下來我要給您講解的內(nèi)容十分關(guān)鍵,請您務(wù)必留意。
在繼續(xù)后面的學(xué)習(xí)以前我們先來問您個問題。假如客戶端的心跳間隔時間是60秒,那么服務(wù)端是不是每隔60秒就檢查一次客戶端是否發(fā)來心跳請求呢?
我們本節(jié)課剛開始的時候曾給大家介紹過,如果客戶端在心跳時間間隔內(nèi)發(fā)布了消息給服務(wù)端,那么服務(wù)端不需要客戶端發(fā)送心跳請求也可以確定該客戶端肯定在線。

但是當(dāng)客戶端在心跳間隔內(nèi)沒有發(fā)布消息給服務(wù)端,這時客戶端會主動發(fā)送一個心跳請求消息給服務(wù)端。以表明自己仍讓在線

簡而言之,客戶端在心跳間隔時間內(nèi),如果有消息發(fā)布,那就不發(fā)布心跳請求。但是在心跳間隔時間內(nèi),客戶端沒有消息發(fā)布,那么它就會發(fā)布一條心跳請求給服務(wù)端,這個心跳請求的目的就是為了告訴服務(wù)端,“我還在線,你放心吧?!?/p>
另外,在實際運行中,如果服務(wù)端沒有在1.5倍心跳時間間隔內(nèi)收到客戶端發(fā)布消息(PUBLISH)或發(fā)來心跳請求(PINGREQ),那么服務(wù)端就會認(rèn)為這個客戶端已經(jīng)掉線。
舉例來說,如果心跳時間間隔是60秒。那么服務(wù)端在90秒內(nèi)沒有收到客戶端發(fā)布的消息也沒有收到PINGREQ請求,那么它就會認(rèn)為客戶端已經(jīng)掉線。
另外,心跳機制不僅僅用于服務(wù)端判斷客戶端是否在線。客戶端也可以利用這一機制來判斷自己是否與服務(wù)端仍保持連接。如果客戶端發(fā)送了心跳請求(PINGREQ)給服務(wù)端一段時間后,仍然沒有收到服務(wù)端回復(fù)的心跳確認(rèn)。那么客戶端也會認(rèn)為自己已經(jīng)斷開了與服務(wù)端的連接。
了解了MQTT心跳機制后,不知道您有沒有想過,如果服務(wù)端知道了某一臺客戶端已經(jīng)掉線,它會采取什么措施嗎?關(guān)于這個問題答案,我們將在下一節(jié)課為您講解。敬請關(guān)注~