- MQTT是什么猜嘱?
mqtt的官方文檔
Github上有中文翻譯
https://github.com/mcxiaoke/mqtt
以上文檔均為mqtt協(xié)議的說明辈赋,沒有具體如何使用的指導罐监,深入研究協(xié)議的可以看涌献。
1. Why MQTT描孟?
某云的文檔是這樣說的
(原文鏈接
https://help.aliyun.com/document_detail/42419.html )
反正就是愧薛,如果不想用市面上的諸如環(huán)信融云等第三方IM庫,讓后臺人員買個好點的服務器掏愁,自己做IM歇由。
2. 集成 MqttAndroidClient
實際上在gradle sync的時候,service包會報異常
『Error:Failed to resolve: org.eclipse.paho:org.eclipse.paho.android.service:1.1.0』
所以建議是在github上下載Android Demo果港,把整個service 包當一個單獨的module沦泌,作為jar包,編譯到你的項目中
service里包含了client的jar包辛掠,所以就不用去sync下載了谢谦。
推薦使用:
eclipse出品Android Demo
https://github.com/eclipse/paho.mqtt.android
2.1初始化
mqtt的生命周期不應該綁在某個activity上,建議傳getApplicationContext(),使其與整個應用共存亡。
初始化一個mqttClient,實際上整個應用也只需要存在一個mqttClient。
connectiOption默認構(gòu)造器屬性琅摩,userName和password找后臺要盗蟆。
自動重連是默認關閉的,設置開啟后预柒,會在掉線的情況下每隔1秒請求一次队塘;
設置超時,setConnectionTimeout宜鸯,timeout默認是30秒憔古;
cleanSession,默認開啟淋袖,每斷一次鸿市,就清除這個鏈接,方便后臺管理即碗。
經(jīng)調(diào)試焰情,建議關閉自動重連,在mqttCallbackExtened和MqttActionListener里做重連處理剥懒。
2.2 開始連接
client設置mqttCallbackExtened回調(diào)和MqttActionListener監(jiān)聽
mqttCallbackExtened需要實現(xiàn)的方法内舟。這里的messageArrived貌似并未響應接收的消息隊列。
重點關心以下
connectComplete
如果需要保持某個會話長時間保存初橘,那么在connectOption里setCleanSession為false,
因為業(yè)務要求验游,我這里并不需要保存長會話,斷線后就重新生成id保檐,重新訂閱耕蝉,服務器也不用管理斷線的會話,定時清理展东,減少后臺壓力赔硫。
connectionLost
之前有提到,不設置自動重練盐肃,那么應該要做手動重連的處理爪膊。
我這里先保存了斷開連接的日志,方便查錯砸王,然后setClientID----重新生成id用于建立新會話推盛,5秒后請求連接。
同樣的谦铃,在成功后訂閱主題耘成。
失敗,記錄日志,5秒后重連瘪菌。
問題來了:
為什么不在mqttCallBackExtend的onSuccess里訂閱主題撒会,而要在Listener里訂閱?
mqttCallBackExtend的onSuccess先被觸發(fā)师妙,
然后才走IMqttActionListener的onSuccess或onFailure
可以認為诵肛,只有后者成功走onSuccess,整個訂閱才算成功默穴。
或者說怔檩,mqttCallBackExtend著眼在client和服務器的連接是否成功,不管會話的建立是否成功蓄诽,后者重點在會話的建立薛训。(這里有點模糊,我有空再查查資料)
2.3訂閱主題
其實這里訂閱只需要設置IMqttMessageListener就可以了仑氛,
messageArrived方法處理接收到的消息乙埃,根據(jù)接收到的topic進行分類處理。
此處我是用EventBus分發(fā)所有接到的消息锯岖,在fragment或者Activity里處理對應topic
附mqtt的消息類型(messageId用來保證該條消息的唯一性膊爪,可做去重判斷)
在訂閱的時候,需要注意的是嚎莉,重復訂閱相同主題沒有問題米酬,且相比重新連接消耗低。
例子:
在保證不斷線的情況下趋箩,
A循環(huán)操作 訂閱赃额,取消訂閱,訂閱叫确,取消訂閱…
和循環(huán)操作 開鏈接跳芳,訂閱,取消訂閱竹勉,關連接飞盆。
同一個用戶可以同時訂閱多個主題,不同的用戶訂閱的主題不一樣次乓,
這里采取的方案是吓歇,每訂閱一個主題topic,就把這個topic存入一個list票腰,
取消訂閱則把該topic從list中移除城看,
遇到斷線需要重新連接的時候,循環(huán)訂閱該list中的主題杏慰。
當然测柠,mqqttClient.subscribe()提供了一次訂閱多個主題的方法炼鞠,當然也需要同時傳入多個IMqttMessageListener,這相當于要開發(fā)者同時維護幾個list(當然也可以寫個map)
看業(yè)務復雜度吧轰胁,這里對消息的處理比較簡單谒主,只管接收,接到就發(fā)出去赃阀。
2.4取消訂閱
2.5釋放資源
從搭建mqtt的準備工作就可以看出瘩将,我們用的eclipse這個demo,本質(zhì)上就是一個service凹耙,如果綁定的是某Activity,Activity被干掉肠仪,當然就has leaked了肖抱。(Service被干調(diào),但連接一直保持)
順序調(diào)用client.close –》client.unRegisterResource
敲黑板:可我干嘛要釋放這個資源呢异旧?我初始化的時候意述,綁定的就是整個應用的生命周期,service一直在后臺運行著吮蛹,接收訂閱的消息荤崇,
開發(fā)者只要關心:用戶訂閱了哪個主題,又取消訂閱了哪個主題潮针,在哪個界面處理哪個主題术荤。
參考鏈接:
http://lilei.work/2016/02/25/Android-Performance-Patterns-s5ep10-Profile-GPU-Rendering/
http://stackoverflow.com/questions/33451381/colors-of-profile-gpu-bars-on-android-m
https://developer.android.google.cn/studio/profile/am-gpu.html