這里是在 Linux
上使用 Swift
來編寫MQTT客戶端系列的一篇文章。
在這篇文章里,我們將著眼在 MQTT
的遺愿消息。一般是連接著代理程序的客戶端預定義好 LWT
(Last Will and Testament)的。如果客戶端異常地斷開連接,代理程序(the broker)將會廣播 LWT
消息到所有訂閱者的客戶端中。
比如說,你正在搭建一個聊天應用,每個客戶端與代理程序連接著并且訂閱了/chat/hottub
,被發布到/chat/hottub
的消息被所有的訂閱者接收。加入一個“聊天室”是一簡單有效的方法(比如:MQTT
主題)。
在正常情況下,一個客戶端主動退出的時候,我們一般會期待看見這樣的消息:“Joe 離開了/chat/hottub
”。這個實現起來很簡單,在用戶用戶離開的時候,發布一個/exit
的消息然后關閉客戶端。但如果一個客戶端非正常地中斷連接(如網絡異常、客戶端閃退等等),誰來給代理程序發遺愿消息呢。
下面展示如何給 MQTT
客戶端設置遺言:
class Client:MQTT, MQTTDelegate {
init(clientId:String) {
super.init(clientId:clientId)
super.willMessage = MQTTWill(topic:"/chat/hottub",
message:"{\"client\":\"\(clientId)\",\"message\":\"Abnormal Disconnect\"}")
super.delegate = self
}
...
}
willMessage
是 MQTT
的一個 MQTTWill
類型的成員屬性。 MQTTWill
由標題和消息構成。在我們這個例子中標題可以是我們的聊天頻道/chat/hottub
,消息則是由我們客戶端 ID 和一個簡單的異常連接中斷的字符串組成的 JSON 字符串。
獲取代碼
我們搭建程序用的 Swift 3.0
是來自蘋果最新的代碼倉庫的,并且有持續更新我們程序的代碼。需要先按照我們的apt-get倉庫安裝 Swift 3.0
。
我們 MQTT
聊天室的例子在GitHub上。
# git clone https://github.com/iachievedit/MQTTHotTub
# cd MQTTHotTub
# swift build
出于測試的目的,需要運行 MQTTHotTub
兩回,所以需要打開兩個終端。
用這個命令運行客戶端 .build/debug/MQTTHotTub
。
Prisencolinensinainciusol
我們的客戶端 MQTTHotTub
模擬了一個語無倫次聊天對話。發布的每條消息都是以 JSON
格式的傳遞的。
{"client":"octxktfo", "message":"Gyxswhz nsoxfnj gz."}
{"client":"ajyhyjic", "message":"Cmr w bzwubzv mwfhtklz."}
當一個客戶端接收到一條不是自己發布的消息,會有過濾消息的過程:
if cid != clientId {
SLogInfo("Received \"\(msg)\" from \(cid)")
}
如果我們監聽發送給一個特定主題的消息,并且我們也向那個主題發送消息。就像回聲一樣,客戶端將也會接受到自己發布的消息。這就是用 cid != clientId
來過濾的目的了。
可以觀察到每個客戶端控制臺打印記錄,看看他們從別的客戶端接收到的消息:
Received "Wlfu zrqyj tady obxnjl lupihobi nph oapplt nyidmja." from octxktfo
Received "Cmr w bzwubzv mwfhtklz." from ajyhyjic
現在, CTRL-C
其中一個客戶端,注意到剩下的其他客戶端接收到的消息:
Received "Abnormal Disconnect" from octxktfo
以上就是 MQTT
的遺愿消息的實操啦。中斷連接的客戶端沒有機會去廣播自己要退出,所以代理程序代替它發布了客戶端的死前遺言到對話/聊天室:
{"client":"\(clientId)","message":"Abnormal Disconnect"}
必須要有死前遺言嗎
必須這個詞太嚴肅了,這個問題的答案是 “不”,你的 MQTT
客戶端不需要提供一個遺愿消息。如果你想要提供的話,這里有很多的其他案例可以指導你。
接下來的計劃
我們繼續地很努力地研究在 Linux
上使用 Swift
來實現MQTT。在這篇文章后,我們的將專注于實現 MQTT
的安全連接(MQTT SSL
)上。
本文由 SwiftGG 翻譯組翻譯,已經獲得作者翻譯授權,最新文章請訪問 http://swift.gg。