Mqtt 记录

package com.jd.aiadAndroid.commonlib.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import com.google.gson.JsonObject;
import com.jd.aiadAndroid.commonlib.bean.Audio;
import com.jd.aiadAndroid.commonlib.bean.Reboot;
import com.jd.aiadAndroid.commonlib.bean.ScreenShot;
import com.jd.aiadAndroid.commonlib.bean.SoftDeviceOff;
import com.jd.aiadAndroid.commonlib.bean.Topics;
import com.jd.aiadAndroid.commonlib.interfaces.IOnPlayStrategyArrivedCallback;
import com.jd.aiadAndroid.commonlib.utils.BaseUtil;
import com.jd.aiadAndroid.commonlib.utils.Constants;
import com.jd.aiadAndroid.commonlib.utils.GsonUtil;
import com.jd.aiadAndroid.commonlib.utils.JsonObjectBuilder;
import com.jd.aiadAndroid.commonlib.utils.SPUtils;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;

import java.util.HashMap;

import static org.eclipse.paho.client.mqttv3.MqttConnectOptions.MQTT_VERSION_3_1_1;

/**
 * MQTT长连接服务
 *
 * @author cjq
 * @version 创建时间:2019/01/19 16:06
 */
public class MqttService extends Service {

    public static final String TAG = MqttService.class.getSimpleName();
    private static MqttAndroidClient client;
    private MqttConnectOptions conOpt;
    private static IOnPlayStrategyArrivedCallback mOnPlayStrategyArrived;
    private static Integer requestId = 0;
    private boolean isFirst = true;
    public static HashMap requestCallBackListeners = new
            HashMap<>();

    public static void setOnPlayStrategyArrivedCallback(IOnPlayStrategyArrivedCallback onPlayStrategyArrivedCallback) {
        mOnPlayStrategyArrived = onPlayStrategyArrivedCallback;
    }

    public interface OnRequestCallBackListener {
        void onRequestCallBack(String response);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: startId = " + startId);
        init();
        return START_STICKY;
    }

    public class MyBinder extends Binder {
        public MqttService getService() {
            return MqttService.this;
        }
    }

    private MyBinder myBinder = new MyBinder();

    @Override
    public IBinder onBind(Intent intent) {
        init();
        return myBinder;
    }

    public static void request(String topic, String msg, OnRequestCallBackListener
            requestCallBackListener) {
        try {
            Integer qos = 1;
            Boolean retained = false;
            int reqid = requestId++;
            JsonObjectBuilder build = new JsonObjectBuilder();
            build.append("reqId", reqid);
            JsonObject body = new JsonObject();
            body.addProperty("msg", msg);
            body.addProperty("route", "/aaaa");
            build.append("body", body);
            requestCallBackListeners.put(reqid, requestCallBackListener);
            if (client.isConnected()) {
                IMqttDeliveryToken token = client.publish(topic, build.toString().getBytes(), qos
                        .intValue(), retained.booleanValue());
                Log.i(TAG, "AiAD.LOG Mqtt request: token = " + token.getMessage().toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void init() {
        // 服务器地址(协议+地址+端口号)
        client = new MqttAndroidClient(this, Topics.TCP_URL, Topics.PREFIX + Topics.CLIENT_ID);
        // 设置MQTT监听并且接受消息
        client.setCallback(mqttCallback);
        conOpt = new MqttConnectOptions();
        // 设置超时时间,单位:秒
        conOpt.setConnectionTimeout(1);
        // 心跳包发送间隔,单位:秒
        conOpt.setKeepAliveInterval(20);
        //自动重连
        conOpt.setAutomaticReconnect(true);
        conOpt.setMqttVersion(MQTT_VERSION_3_1_1);
        conOpt.setCleanSession(false);//默认为true,为实现离线推送给,将其保留
        // 用户名
        conOpt.setUserName(Topics.USERNAME);
        // 密码
        conOpt.setPassword(Topics.PASSWORD.toCharArray());

        Integer qos = 1;
        Boolean retained = false;
        Boolean doConnect = true;
        // 最后的遗嘱
        try {
            conOpt.setWill(Topics.GLOBAL_REQ + "disconnect", "Connection Closed".getBytes(), qos
                    .intValue(), retained.booleanValue());
        } catch (Exception e) {
            Log.i(TAG, "Mqtt Connection Exception Occured", e);
            doConnect = false;
            iMqttActionListener.onFailure(null, e);
        }

        //开始连接
        if (doConnect) doClientConnection();
    }

    @Override
    public void onDestroy() {
        try {
            Log.i(TAG, "AiAD.LOG Mqtt onDestroy");
            if (client != null) {
                client.unregisterResources();
                client.close();
                client = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }

    /**
     * 连接MQTT服务器
     */
    private void doClientConnection() {
        while (true) {
            try {
                if (client != null && !client.isConnected()) {
                    client.connect(conOpt, this, iMqttActionListener);
                    break;
                } else {
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    // MQTT是否连接成功
    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {

        @Override
        public void onSuccess(IMqttToken arg0) {
            Log.i(TAG, "AiAD.LOG Mqtt Connection 连接成功 ");
            //订阅subscribeTopic话题
            Log.i(TAG, "AiAD.LOG Mqtt onSuccess: SUBSCRIBE_TOPIC_MAC = " + Topics.SUBSCRIBE_TOPIC_MAC);
            subscribeTopics();
        }

        @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            // 连接失败,重连
            Log.i(TAG, "AiAD.LOG Mqtt Connection onFailure--->第一次连接失败");
            doClientConnection();
        }
    };

    private void subscribeTopics() {
        try {
            if (!isFirst) return;
            if (client == null) return;
            client.subscribe(Topics.SUBSCRIBE_TOPIC, 1);
            client.subscribe(Topics.SUBSCRIBE_TOPIC_MAC, 1);
            client.subscribe(Topics.GLOBAL_PUSH, 1);
            Log.i(TAG, "AiAD.LOG Mqtt subscribeTopics 订阅成功");
            //客户端发送defaultTopic请求
//            request(Topics.DEFAULT_TOPIC, "bababaab", new OnRequestCallBackListener() {
//                @Override
//                public void onRequestCallBack(String response) {
//
//                }
//            });
            isFirst = false;
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    // MQTT监听并且接受消息
    private MqttCallbackExtended mqttCallback = new MqttCallbackExtended() {
        @Override
        public void connectComplete(boolean reconnect, String serverURI) {
            Log.i(TAG, "AiAD.LOG Mqtt connectComplete: reconnect = " + reconnect);
        }

        /**
         * 连接服务器成功后,服务器应答信息格式:
         *
         * @param topic 话题
         * @param message 下发的消息
         */
        @Override
        public void messageArrived(String topic, MqttMessage message) {
            try {
                String str1 = new String(message.getPayload());
                
              
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0) {

        }

        @Override
        public void connectionLost(Throwable arg0) {
            if (!BaseUtil.isNetworkAvailable(MqttService.this)) {
                Log.i("connectionLost", "AiAD.LOG Mqtt Connection connectionLost--->网络不可用");
            }
            // 失去连接,重连
            if (arg0 != null)
                Log.i("connectionLost", "AiAD.LOG Mqtt Connection connectionLost--->失去连接,重连" + arg0.getMessage());
            doClientConnection();
        }
    };
}

注意事项:

1.bindservice()

2.结束程序时候,必须先unbinddervice(),关闭mqtt client,否则client非正常关闭,下次重启会有 重复消息推送,应该是本地缓存的,不是service的

3.setCleanSession(false);//默认为true,为实现离线推送设置为false

你可能感兴趣的:(android技术)