mqtt開發總結

源碼解析博客推薦

https://juejin.im/post/5cd66c4af265da037516bec3

1.遇到的問題

1.1同一設備,多次創建mqtt client

在最開始的代碼實現中,發現同一個設備有兩個client。因爲我在client的定義上有增加timestamp作爲參數的一部分,而timestamp在獲取的時候是根據當前時間動態獲取的,這導致我在service多次啓動中,創建了多個client。

在mqtt的client中,一個clientID可以創建一個mqtt的連接,如果出現了兩個以上,那麼說明一定是clientID不同導致的。

1.2斷線重連導致陷入死循環

 

最開始設計斷線重連的時候,client調用的callback是:mqttcallback,這個回調需要手動處理斷線重連狀態。

​
//訂閱主題的回調【setAutomaticReconnect設置false調用該回調】
    private MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void connectionLost(Throwable cause) {
            LogUtils.d("mqtt", "mqttCallback>>連接中斷");
            //doClientConnect();//再次連接,這種寫法會導致異常:不停的斷線重連
//            try {
//                Thread.sleep(30000);
//                reConnect();
//            }catch (InterruptedException e){
//                e.printStackTrace();
//            }catch (Exception e){
//                e.printStackTrace();
//            }
        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            LogUtils.d("mqtt", "消息獲得");
            LogUtils.d("mqtt", "topic : " + topic);
            LogUtils.d("mqtt", "message : " + message.toString());


        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {

        }
    };

​

我在connectLost中再次做了

mqttAndroidClient.connect(mqttConnectOptions, null, mqttActionListener);

請求,這裏會出現一個情況:

如果再次連接成功,那麼mqtt會調用斷開之前的連接,並再次做新的連接,然後陷入死循環。

原因:

這是一種異常情況,就是在斷線連接之後的再次連接,創建了一個新的client,而新的client連接的時候,會導致之前的連接斷開,會執行connectionLost方法,而connectionLost方法的執行又會再次連接,導致新的client斷開,然後觸發connectionLost,就陷入死循環。而這種異常情況的來源是兩個client導致的。

所以,方法就是調用mqtt提供的斷線重連方法,而非手動去斷線重連。同時,避免創建兩個client。

代碼更改爲:

mqttConnectOptions.setAutomaticReconnect(true);//斷線重連

同時設置setCallback爲:MqttCallbackExtended

MqttCallbackExtended會在斷線重連成功之後調用

connectComplete

在方法裏面重新訂閱需要的topic,不然無法收到服務器的消息

這樣也可以解決手動重連需要做循環導致UI線程阻塞的問題。

1.3關閉close mqtt的時候導致內存泄漏

https://blog.csdn.net/hacker_crazy/article/details/103489861

目前的解決方法是退出應用不關閉mqtt的service。

1.4 MQTT斷開連接的時候調用順序:

 mqttAndroidClient.close();
        mqttAndroidClient.unregisterResources();
        try {
            if (mqttAndroidClient != null) {
//                LogUtils.d("mqtt", "clientId : " + mqttAndroidClient.getClientId());
                mqttAndroidClient.disconnect();
                //mqttAndroidClient.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.d("mqtt", "exception 1 : " + e.getLocalizedMessage());
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章