CocoaMQTT -MQTT Keep Alive
目錄
1. MQTT
2. CocoaMQTT Keep Alive
2-1 MQTT3.1.1
2-2 MQTT5
2-3 LWT
⦿ MQTT
⦿ CocoaMQTT Keep Alive
⦿ MQTT3.1.1
⦿ MQTT5
⦿ LWT
MQTT
在物聯網中,應用層
協議我們常使用 MQTT,MQTT 相較於 HTTP 建立連線、斷線重連機制,是一個輕量化的協議,我們當然可以隨時 Call HTTP API,不過這一來一回(Request、Response)的速度
等開銷就不若 MQTT 來的有利。
在 MQTT 裡,我們使用的是訂閱發佈(Subscribe、Publish)的方式,來讓設備端(Client)、控制端(APP or Broker),或是邊緣端(Edge)能夠隨著接收到的訊息作動。
當然,在物聯網中還有許多其他的協議值得研究,比方 Thread、Zigbee⋯⋯等,暫不在此篇文章的討論當中,但我們必須要知道有些協議其實是跨 OSI 的,就好比現在上網的人們是使用 TCP/IP 這個 IPS(Internet Protocol Suite),我們不會說上網是使用 TCP 連接,而排除 IP Address,甚至忽略 MAC Address。
OSI 是為我們刻繪出那看不見的東西,幫助理解進入連接、網路世界的核心概念,不過肉眼真實可見的大概就是物理層
了,使用以太網路線,你可以看到 RJ45
的接頭,剝開網路線,可以看到四對銅絞線
,打開 MCU,你可以看到 Tx、Rx 那 UART
的焊點,這些東西在我的文章中或可發現其蹤跡。
倘若要解析序列埠
傳來的訊號,沒有示波器
顯示的圖形,將會很難想像 Data 是什麼,又或者你在程式碼中看到 0x51
,或對二進位
的 Data 沒有感覺這是很正常的,不過物理層之外的其他層,函式庫也都幫你解決了。
CocoaMQTT Keep Alive
重點回顧,在執行 MQTT 連接後,比方說 Device
跟 Broker
之間如果持續沒有其他動作,那我們如何能確定他們仍保持連接呢?
這即是 Keep-Alive 的作用。
起始線為虛線,若 Keep-Alive 設定為 30
秒,而每一分鐘
Client 會固定傳送 Data 到 Broker,那麼在第一個 30 秒,Client 會發送 PINGREQ
給 Broker,Broker 也會傳送 PINGRESP
給 Client, 如此確認連接。
再 30 秒後 Data 開始傳送,既然有 Payload 就不用再送 PING,直到下一個 30 秒。
MQTT3.1.1
我們使用 CocoaMQTT 這個套件,你可以用 pod 來管理 dependency,或其他方式,接著,以 default host 為 broker-cn.emqx.io
這個 broker 來舉例,在 CocoaMQTT 中會看到如下:
CocoaMQTT(debug): ping
CocoaMQTT(debug): SEND: PING
CocoaMQTT(debug): =========================MQTT 3.1.1=========================
CocoaMQTT(debug): packetFixedHeaderType 192
CocoaMQTT(debug): remainingLen(len: len) [0]
CocoaMQTT(debug): variableHeader []
CocoaMQTT(debug): payload []
CocoaMQTT(debug): =============================================================
[TRACE] [mqttDidPing(_]:
CocoaMQTT(debug): socket wrote data -192
CocoaMQTT(debug): RECV: PONG
[TRACE] [mqttDidReceivePong(_]:
這意思是說,雙方有段時間沒聯繫了,由我方發動 ping(即 PINGREQ),在 MQTT 3.1.1 下,header type 是 192。
/// MQTT Frame Type
enum FrameType: UInt8 {
...
case pingreq = 0xC0
case pingresp = 0xD0
...
}
去找到 CocoaMQTT 的 FrameType 會發現 pingreq 是 0xC0
,經過 16 進制(Hex)與 10 進制(Decimal)的轉換就是 192
。
既然只要 Ping Request,所以 payload 與 variableHeader 自然是空的,那麼,加起來的長度(remainingLen)也就會是 0。
並且看到這期間調用的 func 有 mqttDidPing
、mqttDidReceivePong
,即是用來追蹤我方送 PING,以及收到 PONG(回應)是什麼時候。
MQTT5
同樣地,在使用 MQTT5 時,也可以追蹤 Keep-Alive 機制如何作動,若只取呼叫 function 前後,會出現如下:
[TRACE] [mqtt5DidPing(_]:
[TRACE] [mqtt5DidReceivePong(_]:
[TRACE] [mqtt5DidPing(_]:
[TRACE] [mqtt5DidReceivePong(_]:
[TRACE] [mqtt5DidPing(_]:
[TRACE] [mqtt5DidReceivePong(_]:
如果 mqtt!.keepAlive = 60
或 mqtt5!.keepAlive = 60
,這表示一分鐘內 client 若沒有 payload 傳送到 Server,就會發送空的 payload 到 Server 來做連接確認。
LWT
同樣在 CocoaMQTT,我們可以設置 Last Will and Testament
,遺囑訊息,以 MQTT5 舉例如下:
let lastWillMessage = CocoaMQTT5Message(topic: "/will", string: "dieout")
lastWillMessage.contentType = "JSON"
lastWillMessage.willResponseTopic = "/will"
lastWillMessage.willExpiryInterval = .max
lastWillMessage.willDelayInterval = 0
lastWillMessage.qos = .qos1
這個例子中可以看到這個遺囑訊息是 JSON
格式,在斷線會發出 dieout
這個 String,並且發在 /will
這個 topic,並以 QoS 1
(至少一次)來發送。
這次就分享到這,感謝您的閱讀。
繼續閱讀|回目錄