Android使用MQTT通訊

前言

主要講下Android如何使用MQTT通訊。用到的軟件或者框架有:

EMQ:https://www.emqx.io/cn/
org.eclipse.paho的MQTT通訊框架:https://github.com/eclipse/paho.mqtt.android

如果已經(jīng)有MQTT相關(guān)服務(wù)胞谭,可以跳過(guò)第一項(xiàng)抵乓,從第二項(xiàng)開(kāi)始看听绳。

一失暴、安裝EMQ及啟動(dòng)EMQ

1.安裝所需要的依賴(lài)包

$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2

2.使用以下命令設(shè)置穩(wěn)定存儲(chǔ)庫(kù),以 CentOS7 為例

$ sudo yum-config-manager --add-repo https://repos.emqx.io/emqx-ce/redhat/centos/7/emqx-ce.repo

3.安裝最新版本的 EMQ X

$ sudo yum install emqx

4.安裝特定版本的 EMQ X

  • 查詢(xún)可用版本
$ yum list emqx --showduplicates | sort -r

emqx.x86_64                     3.1.0-1.el7                        emqx-stable
emqx.x86_64                     3.0.1-1.el7                        emqx-stable
emqx.x86_64                     3.0.0-1.el7                        emqx-stable
  • 根據(jù)第二列中的版本字符串安裝特定版本棕洋,例如 3.1.0
$ sudo yum install emqx-3.1.0

5.啟動(dòng) EMQ X

  • 直接啟動(dòng)
$ emqx start
emqx 3.1.0 is started successfully!

$ emqx_ctl status
Node 'emqx@127.0.0.1' is started
emqx v3.1.0 is running
  • systemctl 啟動(dòng)
$ sudo systemctl start emqx
  • service 啟動(dòng)
$ sudo service emqx start

EMQ管理后臺(tái)

地址:xxx.xxx.xxx:18083挡闰,地址為服務(wù)器ip或者域名,端口為18083端口


image.png

二掰盘、Android使用MQTT

1.在Android中導(dǎo)入依賴(lài)

    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0'

項(xiàng)目地址:https://github.com/eclipse/paho.mqtt.android
2.創(chuàng)建MQTT連接的一個(gè)Service

public class MqttMessageService extends Service {
 
    /**
     * 訂閱的主題
     */
    private String subTopic;
    @Override
    public void onCreate() {
        super.onCreate();
        //初始化mqtt配置
        initMqtt();
        //連接mqtt
        connectMqtt();

    }



    /**
     * 連接mqtt
     */
    private void connectMqtt() {

        try {
            mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {

                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    LogUtils.e("MQTT連接失斏忝酢!@⒉丁I菅薄!" + exception.getCause());
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            LogUtils.e("30s后次绘,嘗試重新連接" );
                            try {
                                Thread.sleep(1000*30);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            connectMqtt();
                        }
                    }).start();
                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    /**
     * mqtt初始化
     */
    private void initMqtt() {
        try {

           //寫(xiě)上自己的url
            String uri = "";
            subTopic = "topic_test" ;
            mqttAndroidClient = new MqttAndroidClient(
                    getApplicationContext(),
                    uri, "test");
            mqttAndroidClient.setCallback(new MqttCallbackExtended() {
                @Override
                public void connectComplete(boolean reconnect, String serverURI) {
                    if (reconnect) {
                        LogUtils.i("MQTT重新連接成功瘪阁!serverURI:" + serverURI);
                    } else {
                        LogUtils.i("MQTT連接成功撒遣!serverURI:" + serverURI);
                    }
                    subscribeAllTopics();
                }

                @Override
                public void connectionLost(Throwable cause) {
                    LogUtils.i("MQTT連接斷開(kāi)!" + cause.getCause());
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) {
                    LogUtils.i("收到了消息:"+topic+ message.toString()+ message.getQos());
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    try {
 //                   MqttMessage mqttMessage = token.getMessage();
//                    LogUtils.i("消息發(fā)送成功:" + mqttMessage.toString());
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                }
            });

            // 新建連接設(shè)置
            mqttConnectOptions = new MqttConnectOptions();
            mqttConnectOptions.setUserName(MqttConfig.EMQ_USERNAME);
            mqttConnectOptions.setPassword(MqttConfig.EMQ_PASSWORD.toCharArray());
            //斷開(kāi)后管跺,是否自動(dòng)連接
            mqttConnectOptions.setAutomaticReconnect(true);
            //是否清空客戶(hù)端的連接記錄义黎。若為true,則斷開(kāi)后豁跑,broker將自動(dòng)清除該客戶(hù)端連接信息
            mqttConnectOptions.setCleanSession(true);
            //設(shè)置超時(shí)時(shí)間廉涕,單位為秒
            mqttConnectOptions.setConnectionTimeout(15);
            //心跳時(shí)間,單位為秒艇拍。即多長(zhǎng)時(shí)間確認(rèn)一次Client端是否在線(xiàn)
            mqttConnectOptions.setKeepAliveInterval(30);
            //允許同時(shí)發(fā)送幾條消息(未收到broker確認(rèn)信息)
            mqttConnectOptions.setMaxInflight(30);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 訂閱所有主題
     */
    private void subscribeAllTopics() {
        //訂閱主消息主題和更新消息主題
        subscribeToTopic(subTopic , 2);
    }


    /**
     * 訂閱一個(gè)主主題
     *
     * @param subTopic 主題名稱(chēng)
     */
    private void subscribeToTopic(String subTopic, int qos) {
        try {
            mqttAndroidClient.subscribe(subTopic, qos, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    LogUtils.i("MQTT訂閱消息成功:" + subTopic);
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    LogUtils.d("MQTT訂閱消息失敽伞!" + subTopic);
                }
            });
        } catch (MqttException ex) {
            LogUtils.d("subscribeToTopic: Exception whilst subscribing");
            ex.printStackTrace();
        }
    }

    /**
     * 發(fā)布主題
     *
     * @param topic 主題
     * @param msg   內(nèi)容
     * @param qos   qos
     */
    public void publishMessage(String topic, String msg, int qos) {
        if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {
            try {
                LogUtils.d("publishMessage: 發(fā)送" + msg);
                mqttAndroidClient.publish(topic, msg.getBytes(), qos, false);
            } catch (Exception e) {
                LogUtils.e("publishMessage: Error Publishing: " + e.getMessage());
                e.printStackTrace();
            }
        } else {
            LogUtils.e("publishMessage失敗卸夕,MQTT未連接 ");
        }
    }

    public void publishMessage(String topic, String msg) {
        publishMessage(topic, msg, 2);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return Service.START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        LogUtils.e("關(guān)閉MQTT");
        //斷開(kāi)mqtt連接
        try {
            if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) {
                mqttAndroidClient.disconnect();
                mqttAndroidClient.unregisterResources();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
  
        super.onDestroy();
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末层释,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子娇哆,更是在濱河造成了極大的恐慌湃累,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碍讨,死亡現(xiàn)場(chǎng)離奇詭異治力,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)勃黍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)宵统,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人覆获,你說(shuō)我怎么就攤上這事马澈。” “怎么了弄息?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵痊班,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我摹量,道長(zhǎng)涤伐,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任缨称,我火速辦了婚禮凝果,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘睦尽。我一直安慰自己器净,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布当凡。 她就那樣靜靜地躺著山害,像睡著了一般纠俭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浪慌,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天柑晒,我揣著相機(jī)與錄音,去河邊找鬼眷射。 笑死,一個(gè)胖子當(dāng)著我的面吹牛佛掖,可吹牛的內(nèi)容都是我干的妖碉。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼芥被,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼欧宜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起拴魄,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冗茸,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后匹中,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體夏漱,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年顶捷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挂绰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡服赎,死狀恐怖葵蒂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情重虑,我是刑警寧澤践付,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站缺厉,受9級(jí)特大地震影響永高,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芽死,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一乏梁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧关贵,春花似錦遇骑、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)亥啦。三九已至,卻和暖如春练链,著一層夾襖步出監(jiān)牢的瞬間翔脱,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工媒鼓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留届吁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓绿鸣,卻偏偏與公主長(zhǎng)得像疚沐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子潮模,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351