MQTT介紹
首先瘫里,我們簡單的提一下mqtt是什么;MQTT(Message Queuing Telemetry
Transport荡碾,消息隊(duì)列遙測傳輸)是IBM開發(fā)的一個(gè)即時(shí)通訊協(xié)議谨读,有可能成為物聯(lián)網(wǎng)的重要組成部分。該協(xié)議支持所有平臺(tái)坛吁,幾乎可以把所有聯(lián)網(wǎng)物品和外部連接起來劳殖,被用來當(dāng)做傳感器和致動(dòng)器(比如通過Twitter讓房屋聯(lián)網(wǎng))的通信協(xié)議。
上面的這些語言都太官方了拨脉,我覺得總結(jié)一句話就是:連上mqtt之后哆姻,服務(wù)器那邊就可以在你不斷的情況下給你推送數(shù)據(jù),并且實(shí)時(shí)性比較好玫膀;
工作原理
現(xiàn)在就讓我們來總結(jié)一下我們所使用的mqtt到底是怎么工作的矛缨,方便以后查閱的時(shí)候少走彎路。
流程圖:
一帖旨、既然要使用官方提供的mqtt協(xié)議箕昭,那么就必須導(dǎo)入官方給出的jar包我們使用的是IBM公司提供的wmqtt.jar包。
二解阅、既然要讓它一直在后臺(tái)運(yùn)行落竹,則必須通過服務(wù)來運(yùn)行,后臺(tái)常駐才符合我們的要求货抄。
既然是鏈接前后臺(tái)的服務(wù)器述召,那么鏈接的狀態(tài)可能要分很多種,例如:
就會(huì)有以上的六種狀態(tài)信息碉熄;鏈接的狀態(tài)是通過發(fā)送廣播的形式發(fā)送的:
(1)桨武、斷開鏈接的廣播:
(2)、嘗試鏈接锈津,但未鏈接上:
(3)呀酸、鏈接斷開,重新鏈接:
(4)琼梆、由于其他的原因?qū)е聼o法鏈接:
(5)性誉、鏈接成功:
(6)、未能鏈接上:
每一種鏈接的狀態(tài)都會(huì)發(fā)送相應(yīng)的狀態(tài)信息茎杂,在log中打印出來错览,讓我們很直觀的看到此時(shí)的mqtt處于哪一種狀態(tài)。
三煌往、我們?cè)阪溄觤qtt的時(shí)候需要先定義一個(gè)鏈接的接口:
mqttClient = MqttClient.createMqttClient(mqttConnSpec,usePersistence);
String mqttConnSpec = "tcp://" + brokerHostName + "@"+ brokerPortNumber;
詳細(xì)信息是:“tcp://ip@1883”倾哺;
private boolean connectToBroker()這個(gè)方法是判斷當(dāng)前的鏈接是否存在轧邪,存在返回true,不存在返回false羞海,然后在執(zhí)行后面的操作忌愚;
// try to connect
mqttClient.connect(generateClientId(), cleanStart, keepAliveSeconds);
此時(shí)才是mqtt建立鏈接的操作,第一個(gè)參數(shù)generateClientID()是建立鏈接的一個(gè)關(guān)鍵字却邓,是為了區(qū)分不同的主機(jī)鏈接到mqtt硕糊,方便服務(wù)器那邊進(jìn)行區(qū)分。(“fiber1/Android手機(jī)自帶的序列號(hào)腊徙,這個(gè)碼是唯一的简十,每一部手機(jī)都是不一樣的,這樣才能更好的區(qū)分)撬腾。第二個(gè)參數(shù)是false螟蝙。第三個(gè)參數(shù)是保持心跳,五秒一次时鸵。
上面就已經(jīng)說過了胶逢,當(dāng)它返回的是true的時(shí)候,就說明這個(gè)鏈接已經(jīng)建立成功了饰潜,后續(xù)的操作就是訂閱我們的主題了初坠;
mqttClient.subscribe(topics, parms);
既然有訂閱,那么就必須有取消訂閱彭雾,因?yàn)槿∠嗛喪菫榱俗屛覀兊脑O(shè)備在注銷之后碟刺,不想再收到任何的消息,或者是刪除設(shè)備之后不想再收到任何的消息是一樣的道理薯酝。所以這個(gè)操作是必不可少的半沽。
mqttClient.unsubscribe(topics);
取消訂閱和訂閱的區(qū)別就在于訂閱的時(shí)候需要發(fā)送QoS,而取消訂閱的時(shí)候是不需要發(fā)送QoS的吴菠;
四者填、下面的就是接受廣播:
1、private class BackgroundDataChangeIntentReceiver extends BroadcastReceiver// 接收廣播
我們?cè)谧鲞@件事的時(shí)候做葵,通過請(qǐng)求一個(gè)喚醒鎖占哟,我們要求盡可能的喚醒鎖-只是足夠維持處理器的運(yùn)行,直到我們完成
2酿矢、private class NetworkConnectionIntentReceiver extends BroadcastReceiver
所謂的響應(yīng)于網(wǎng)絡(luò)連接的變化-在連接到服務(wù)器之后榨乎,這讓我們等待,直到我們有一個(gè)可用的數(shù)據(jù)連接
3瘫筐、public class PingSender extends BroadcastReceiver
這個(gè)廣播用于喚醒手機(jī)蜜暑,使手機(jī)可以時(shí)刻接收mqtt的推送消息;
4策肝、public class StatusUpdateReceiver extends BroadcastReceiver
當(dāng)mqtt的客戶端連接的狀態(tài)發(fā)生改變的時(shí)候肛捍,通過StatusUpdateReceiver接收廣播隐绵;
5、public class MQTTMessageReceiver extends BroadcastReceiver
當(dāng)收到mqtt的推送的消息時(shí)篇梭,通過MQTTMessageReceiver接收廣播氢橙;
五、最后就是恬偷,當(dāng)我們收到推送的消息,怎么處理帘睦?比如下面的處理上報(bào)的告警消息
通過異步任務(wù)袍患,將獲取的json數(shù)據(jù)進(jìn)行解析,
public static class AlarmTask extends AsyncTask// 收到告警消息竣付,插入數(shù)據(jù)庫诡延,并且彈出提示界面.
alarmData = jsonobj.geMYSYString("alarm");
......告警處理代碼
注意:在網(wǎng)絡(luò)斷開之后,我們沒有重連的機(jī)制古胆,只有在網(wǎng)絡(luò)重新鏈接上之后肆良,我們才會(huì)去再鏈接mqtt(重連的機(jī)制還是和第一次鏈接的機(jī)制一致),斷網(wǎng)時(shí)逸绎,我們也沒有必要去鏈接惹恃,因?yàn)檫@本身就是不通的,一直鏈接棺牧,反而會(huì)造成阻塞巫糙;