Android 物联网常用网络框架Mqtt

版权声明:未经博主同意切勿转载 https://blog.csdn.net/qq_32136827/article/details/83781383

import android.content.Intent;
import android.util.Log;

import com.sqy.vending.mqttvending_master.app.MyApplication;
import com.sqy.vending.mqttvending_master.bean.MqttMsgEvent;
import com.sqy.vending.mqttvending_master.db.DatabaseUtil;
import com.sqy.vending.mqttvending_master.util.JsonUtil;
import com.sqy.vending.mqttvending_master.util.LogUtils;
import com.sqy.vending.mqttvending_master.util.SharedPreferencesUtil;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.sqy.vending.mqttvending_master.manager.Mqtt.isBoolean;

/**
 * Created by Administrator on 2018/6/7.
 */

public class MqttManager {
    public static String TAG = MqttManager.class.getSimpleName();
    public static MqttManager mInstance = null;
    public MqttClient client;
    public MqttConnectOptions conOpt;
    private ScheduledExecutorService scheduler;
    private boolean clean = true;

    private static volatile boolean hasReConnection = false;

//    private ThreadPoolExecutor executor = new ThreadPoolExecutor();//使用线程池

    public static MqttManager getInstance() {
        if (null == mInstance) {
            mInstance = new MqttManager();
        }
        return mInstance;
    }

    /**
     * 创建 Mqtt 连接
     */
    public boolean createConnect(String brokerUrl, String userName, String password, String clientId) {
        boolean flag = false;
        String tmpDir = System.getProperty("java.io.tmpdir");
        MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(tmpDir);
        Log.e(TAG, "createConnect: brokerUrl:" + brokerUrl + "  userName:" + userName + "  password:" + password + "  clientId:" + clientId);
        try {
            conOpt = new MqttConnectOptions();
            conOpt.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
            conOpt.setCleanSession(clean);
            conOpt.setPassword(password.toCharArray());
            conOpt.setUserName(userName);
            conOpt.setConnectionTimeout(10);    //设置连接超时
            conOpt.setKeepAliveInterval(8);    //设置心跳时长 10*1.5
            client = new MqttClient(brokerUrl, clientId, dataStore);
            client.setCallback(mqttCallback);
            if (client != null) {
                try {
                    client.connect(conOpt);
                    flag = true;
                } catch (Exception e) {
                    flag = false;
                }
            }
        } catch (MqttException e) {
            Log.e(TAG, "createConnect:MqttException: " + e.toString());
        }
        return flag;
    }

    /**
     * 连接服务端
     */
    public void Connect() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                boolean isflag = MqttManager.getInstance().createConnect(Mqtt.Mqtt_Url, Mqtt.Mqtt_UserName, Mqtt.Mqtt_Port, SharedPreferencesUtil.getString("device_id"));
                if (isflag) {
                    subScrbe();
                    Mqtt.isBoolean = true;
                    LogUtils.e(TAG, "连接成功...");
                    Log.e(TAG, "连接成功...");
                } else {
                    LogUtils.e(TAG, "连接失败...");
                    Log.e(TAG, "连接失败...");
                    EventBus.getDefault().post(new MqttMsgEvent(JsonUtil.tipsInfo("连接失败", Mqtt.CONNECTION_FAIL)));
                }
                startReconnect();
            }
        }).start();
    }

    /**
     * 定时器,每隔10秒检查一次mqtt是否连接
     */
    private void startReconnect() {
        Log.e("RE", "startReconnect: 重连::");
        if (scheduler == null) {
            scheduler = Executors.newSingleThreadScheduledExecutor();
            scheduler.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    if (!MqttManager.getInstance().client.isConnected()) {
                        LogUtils.e(TAG, "定时检查到mqtt连接断开...");
                        Log.e("RE", "定时检查到mqtt连接断开...");
                        isBoolean = false;
                        hasReConnection = true;
                        Connect();
                    }
                }
            }, 10 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
        }
    }

    /**
     * 订阅
     */
    public static void subScrbe() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                boolean isflag = MqttManager.getInstance().subScribe(Mqtt.Mqtt_TopDevice + SharedPreferencesUtil.getString("device_id"), 2);
                if (!isflag) {
                    LogUtils.e(TAG, "订阅失败" + SharedPreferencesUtil.getString("device_id"));
                    Log.e(TAG, "订阅失败" + SharedPreferencesUtil.getString("device_id"));
                } else {
                    LogUtils.e(TAG, "订阅成功" + SharedPreferencesUtil.getString("device_id"));
                    Log.e(TAG, "订阅成功" + SharedPreferencesUtil.getString("device_id"));

                    /**
                     * 发送心跳包
                     * 心跳包内容是获取到的设备状态
                     * */
//                    if (hasReConnection) {
                    sendHbPacket();
//                    }
                }
            }
        }).start();
    }

    private static Timer uploadStatusTimer = null;

    /**
     * 发送心跳包
     */
    private static void sendHbPacket() {
        if (uploadStatusTimer == null) {
            uploadStatusTimer = new Timer();
            uploadStatusTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    String json = JsonUtil.uploadDevStatus(DatabaseUtil.getInstance());
                    if (!isBoolean) {
                        LogUtils.e(TAG, "诶呀,还没有连接服务端...");
                    } else {
                        boolean isflag = MqttManager.getInstance().publish(Mqtt.Mqtt_TopService + SharedPreferencesUtil.getString("device_id"), 2, json.getBytes());
                        LogUtils.d("TAG", "心跳包,上报状态=" + json.toString());
                        Log.e("TAG", "心跳包,上报状态=" + json.toString());
                        if (!isflag) {
                            LogUtils.e(TAG, "发送失败");
                        }
                    }
                }
            }, 30 * 1000, 30 * 1000);
        }
    }


    /**
     * 发送心跳包
     *//*
    public static void sendHbPacket(final String json) {
        if (!isBoolean) {
            LogUtils.e(TAG, "诶呀,还没有连接服务端...");
            return;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (json.equals("")) {
                    return;
                }
                while (isBoolean) {
                    LogUtils.e(TAG, "上报状态" + json);
                    boolean isflag = MqttManager.getInstance().publish(Mqtt.Mqtt_TopService + SharedPreferencesUtil.getString("device_id"), 2, json.getBytes());
                    if (!isflag) {
                        LogUtils.e(TAG, "发送失败");
                    }
                    try {
                        Thread.sleep(30 * 1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }*/

    /**
     * 向服务端发送数据
     */
    public static boolean sendData(String json) {
        boolean isflag = false;
        if (json.equals("") || json == null) {
            isflag = false;
            return isflag;
        }
        if (isBoolean) {
            LogUtils.e(TAG, "发送的数据为:" + json);
            Log.e(TAG, "sendData: 发送的数据为:" + json);
            isflag = MqttManager.getInstance().publish(Mqtt.Mqtt_TopService + SharedPreferencesUtil.getString("device_id"), 2, json.getBytes());
        }
        return isflag;
    }

    /**
     * 发送数据到服务端
     */
    public boolean publish(String topicName, int qos, byte[] payload) {
        boolean flag = false;
        if (client != null && client.isConnected()) {
            MqttMessage message = new MqttMessage(payload);
            message.setQos(qos);
            try {
                client.publish(topicName, message);
                flag = true;
            } catch (MqttException e) {
            }
        }
        return flag;
    }

    /**
     * 订阅
     */
    public boolean subScribe(String topicName, int qos) {
        boolean flag = false;
        if (client != null && client.isConnected()) {
            try {
                client.subscribe(topicName, qos);
                flag = true;
//                EventBus.getDefault().post(new MqttMsgEvent("订阅成功"));
                EventBus.getDefault().post(new MqttMsgEvent(JsonUtil.tipsInfo("订阅成功", Mqtt.CONNECTION_SUCCESS)));
            } catch (MqttException e) {
//                EventBus.getDefault().post(new MqttMsgEvent("订阅异常"));
                EventBus.getDefault().post(new MqttMsgEvent(JsonUtil.tipsInfo("订阅异常" + e.toString(), Mqtt.CONNECTION_EXCEPTION)));
            }
        }
        return flag;
    }

    /**
     * 取消连接
     */
    public void disConnect() throws MqttException {
        if (client != null && client.isConnected()) {
            client.disconnect();
//            EventBus.getDefault().post(new MqttMsgEvent("断开连接"));
            EventBus.getDefault().post(new MqttMsgEvent(JsonUtil.tipsInfo("断开连接", Mqtt.DISCONNECT)));
        }
    }

    private MqttCallback mqttCallback = new MqttCallback() {
        /**
         * 接收服务端消息回调
         * */
        @Override
        public void messageArrived(String topic, MqttMessage message) {
            LogUtils.e(TAG, "Server:" + message.toString());
            EventBus.getDefault().post(new MqttMsgEvent(message.toString()));
        }

        /**
         * 与服务端连接丢失,回调此方法,重新连接
         * */
        @Override
        public void connectionLost(Throwable cause) {
            LogUtils.e(TAG, cause.getMessage());
//            EventBus.getDefault().post(new MqttMsgEvent("与服务端连接丢失"));
            EventBus.getDefault().post(new MqttMsgEvent(JsonUtil.tipsInfo("与服务端连接丢失" + cause.toString(), Mqtt.LOST_CONNECTION)));
            isBoolean = false;
            if (uploadStatusTimer != null) {
                uploadStatusTimer.cancel();
                uploadStatusTimer = null;
            }
            Connect();
        }

        /**
         * 与消息相关联的送达令牌
         * 发送消息回调
         * */
        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {

        }
    };

    /**
     * 释放单例, 及其所引用的资源
     */
    public static void release() throws Exception {
        if (mInstance != null) {
            mInstance.disConnect();
            mInstance = null;
        }
    }
}

import com.sqy.vending.mqttvending_master.util.SharedPreferencesUtil;

/**
 * Created by Administrator on 2018/6/11.
 */
public class Mqtt {

    /**
     * mqtt tcp连接地址
     */
    public static String Mqtt_Url = "";

    /**
     * 域名地址
     */
    public static String Mqtt_UserName = "";
//    public static String Mqtt_UserName = String.valueOf(System.currentTimeMillis()/1000);

    /**
     * mqtt连接端口号
     */
    public static String Mqtt_Port = "";

    /**
     * mqtt连接测试Id
     */
//    public static String Mqtt_ClientId;

    /**
     * 发送消息主题
     */
    public static String Mqtt_TopDevice = "";

    /**
     * 订阅主题
     */
    public static String Mqtt_TopService = "";
    ;

    /**
     * 标记是否打开mqtt连接
     */
    public static volatile boolean isBoolean = false;

    public static final String CONNECTION_SUCCESS = "0";
    public static final String CONNECTION_EXCEPTION = "1";
    public static final String DISCONNECT = "2";
    public static final String LOST_CONNECTION = "3";
    public static final String CONNECTION_FAIL = "4";

}

猜你喜欢

转载自blog.csdn.net/qq_32136827/article/details/83781383