mqtt的使用-acu

1获取唯一值
2断线重连啥的

/*
 * Copyright (c) 2021. 版权所有
 */


import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;

import com.aucma.bloodcabinetactivity.utils.GetMac;
import com.aucma.bloodcabinetactivity.utils.LogManager;
import com.aucma.bloodcabinetactivity.utils.MD5Utils;
import com.aucma.bloodcabinetactivity.utils.PassUtils;

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.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MQTTService extends Service {
    public static final String TAG = MQTTService.class.getSimpleName();

    private static MqttAndroidClient client;
    private MqttConnectOptions conOpt;
    GetMac getMac = new GetMac();

    //    public String host = "tcp://192.168.0.17:8089";
//    public String host = "tcp://smarthome.ahlyun.com:8089"; //测试环境域名
//    public String host = "tcp://118.190.172.85:8081";
//    public String host = "tcp://smart.ahlyun.com:8089";
//    public String host = "tcp://miot-hub.ahlyun.com:8071";
//    public String host = "tcp://iot.aucma-medical.com.cn:8071";
    public String host = "tcp://118.190.172.85:8071";
    public String userName = "aohui";
//    public String userName = getMac.getNewMac().replace(":", "");

    //获取当前的毫秒值
    long time = System.currentTimeMillis();
    //将毫秒值转换为String类型数据
    String time_stamp = String.valueOf(time);

    //    public String passWord = "aohui";
    public String passWord1 = time_stamp;

    //        public String clientId = UserInfo.getMac();//客户端标识
    public String clientId = GetMac.getDeviceSN();//客户端标识
    private IGetMessageCallBack IGetMessageCallBack;

    private static String mac;//mac是设备的mac地址

//    private static String BINDE_TOPIC = "/aucma/smartlife/app/bind/"; //mac是设备的mac地址 publish类型
    private static String BINDE_TOPIC = "aohui/accs/real/"; //mac是设备的mac地址 publish类型
    private static String BIND_SUCCESS_TOPIC = "/aucma/smartlife/service/bindSuccess/"; //订阅类型

    public Handler infoHandler;
    //判断操作之后设备给app返回的结果
    private Boolean returnOper = true;

    private ScheduledExecutorService reconnectPool;//重连线程池

    private Handler handler; //掉线重连消息

    @Override
    public void onCreate() {
        Log.e(getClass().getName(), "onCreate");
        String s = GetMac.getNewMac();
        String deviceId=GetMac.getDeviceSN();
        if (!TextUtils.isEmpty(getMac.getNewMac())) {
            init();
        }

//        LogManager.i("生成 mac",s);

    }

    /**
     * 发布消息
     *
     * @param msg
     */
    public static void publish(String msg, String topic, Context context) {
//        String topic = BINDE_TOPIC;
        Integer qos = 1;
        Boolean retained = false;
        try {
            if (client != null && client.isConnected()) {
                //参数分别为:主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
                client.publish(topic, msg.getBytes(), qos.intValue(), retained.booleanValue());
            } else {
                LogManager.i("失败", "client is null");
//                ToastUtils.ToastMsg(context, "绑定失败,请重新绑定");
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }

    }

    //测试接收订阅到的消息
    public static void subscribe(String topic) {
        Integer qos = 1;
        if (client != null && client.isConnected()) {
            try {
                client.subscribe(topic, qos);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }


    private void init() {
        // 服务器地址(协议+地址+端口号)
        String uri = host;
//        client = new MqttAndroidClient(this, uri, clientId) ;
//        // 设置MQTT监听并且接受消息
//        client.setCallback(mqttCallback);

        //防止重复创建MQTTClient实例
        LogManager.i("生成测试", uri + "---" + clientId);
        if (client == null) {
            client = new MqttAndroidClient(this, uri, clientId);
            // 设置MQTT监听并且接受消息
            client.setCallback(mqttCallback);
        }

        conOpt = new MqttConnectOptions();
        // 清除缓存
        conOpt.setCleanSession(true);

        // 设置超时时间,单位:秒
        conOpt.setConnectionTimeout(10);
//        conOpt.setConnectionTimeout(300000);
        // 心跳包发送间隔,单位:秒
        conOpt.setKeepAliveInterval(20);
//        conOpt.setCleanSession(true);
        //断线重连
//        conOpt.setAutomaticReconnect(true);
        // 用户名
        conOpt.setUserName(userName);
        // 测试密码
        String a = PassUtils.getHs(passWord1);
//        LogManager.i("生成后三位",a);
//        LogManager.i("生成md5", MD5Utils.MD5(a+getMac.getNewMac().replace(":","")));
//        LogManager.i("生成mac",getMac.getNewMac().replace(":",""));
//        LogManager.i("生成账号",userName);
        String passWord = "";
        if (!TextUtils.isEmpty(getMac.getNewMac())) {
             passWord = a + MD5Utils.MD5(a + getMac.getNewMac().replace(":", ""));
        }
//        LogManager.i("生成密码",passWord);

        conOpt.setPassword(passWord.toCharArray());     //将字符串转换为字符串数组

        // last will message
        boolean doConnect = true;
        String message = "{\"terminal_uid\":\"" + clientId + "\"}";
        Log.e(getClass().getName(), "message是:" + message);
        String topic = BINDE_TOPIC;
        Integer qos = 1;
        Boolean retained = false;
        if ((!message.equals("")) || (!topic.equals(""))) {
            // 最后的遗嘱
            // MQTT本身就是为信号不稳定的网络设计的,所以难免一些客户端会无故的和Broker断开连接。
            //当客户端连接到Broker时,可以指定LWT,Broker会定期检测客户端是否有异常。
            //当客户端异常掉线时,Broker就往连接时指定的topic里推送当时指定的LWT消息。

            try {
                conOpt.setWill(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
            } catch (Exception e) {
                Log.i(TAG, "Exception Occured", e);
                doConnect = false;
                iMqttActionListener.onFailure(null, e);
            }
        }

        if (client != null && doConnect && isConnectIsNormal()) {
            doClientConnection();
        }

    }

    @Override
    public void onDestroy() {
        stopSelf();
        try {
            if (isConnectIsNormal()) {
                client.disconnect();
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }

    /**
     * 连接MQTT服务器
     */
    private void doClientConnection() {
        if (client != null && !client.isConnected() && isConnectIsNormal()) {
            try {
                client.connect(conOpt, null, iMqttActionListener);
            } catch (MqttException e) {
                e.printStackTrace();
            }

        } else { //这里的逻辑是如果连接不成功就重新连接
            try {
                if (isConnectIsNormal()) {
                    client.disconnect();
                    client.connect(conOpt, null, iMqttActionListener);
                }
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

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

        @Override
        public void onSuccess(IMqttToken arg0) {
            Log.i(TAG, "连接成功 ");
            closeReconnectTask();//关掉断线重连线程
            try {
                // 订阅myTopic话题
//                client.subscribe(BIND_SUCCESS_TOPIC+"a4cf12e8720a", 2);
                if (client != null) {

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //连接失败
        @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            doClientConnection();
        }
    };

    // MQTT监听并且接受消息
    private final MqttCallback mqttCallback = new MqttCallback() {

        //subscribe得到的消息会执行到这里面
        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {

            String str1 = new String(message.getPayload());

            //测试
            if (IGetMessageCallBack != null) {
                IGetMessageCallBack.setMessage(str1);
            }

            //从缓存内取到设备的mac
            SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("deviceMAc", MODE_PRIVATE);
            String deviceMac = sharedPreferences.getString("deviceMac", null);

//            LogManager.i("生成消息",Topic.MEMBERINFOMSG + UserInfo.getHomeId());

            /**
             * 根据topic判断消息来源
             */
//            if (topic.equals(Topic.BIND_SUCCESS_TOPIC + UserInfo.getDeviceMac())) {
            if (topic.equals(Topic.BIND_SUCCESS_TOPIC + UserInfo.getDeviceMacConnect())) {
//                LogManager.i("生成绑定的消息", str1);
//                getBindMsg(str1);
//            } else if (topic.equals(Topic.UNBINDSUCCESS + UserInfo.getDeviceMac())) {
//                LogManager.i("生成解绑的消息", str1);
//                getUnBindMsst(str1);
//            } else if (topic.equals(Topic.MEMBERINFOMSG + UserInfo.getHomeId())) {
//                LogManager.i("生成消息", str1);
//                getMemberMessage(str1);
//                //测试
//            } else if (topic.equals(Topic.INFORMATION + UserInfo.getDeviceMac())) {
//                LogManager.i("生成设备实时信息", str1);
//                getInformaticaMsg(str1);
//            } else if (topic.equals(Topic.DEVICERETURNOPERATION + UserInfo.getDeviceMac())) {
//                LogManager.i("生成设备返回操作信息", str1);
//                getOperationMsg(str1);
//            } else if (topic.equals(Topic.WARNINOFFLINEMSG + UserInfo.getDeviceMac())) {
//                LogManager.i("生成设备离线报警消息", str1);
//                getOffLineMsg(str1);
//            } else if (topic.equals(Topic.SHAREDEVICEMSG + UserInfo.getUserId())) {
//                LogManager.i("生成设备分享消息", str1);
//                getShareDeviceMsg(str1);
//            } else if (topic.equals(Topic.ALLNEWS)) {
//                LogManager.i("生成全体消息", str1);
//                getAllNews(str1);
//            } else if (topic.equals(Topic.WARNINGNEWS + UserInfo.getDeviceMac())) {
//                LogManager.i("生成报警消息", str1);
//                getWarningNews(str1);
//            }

            String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
            Log.i(TAG, "messageArrived:" + str1);
            Log.i(TAG, str2);
        }

        /**
         * 报警消息
         */
        private void getWarningNews(String str1) {

        }

        //获取全部消息
        private void getAllNews(String str1) {
            LogManager.i("生成全部消息", str1);

        }

        /**
         * 设备分享消息
         */
        private void getShareDeviceMsg(String str1) {
            LogManager.i("生成设备分享报警", str1);

        }

        /**
         * 设备离线报警
         * @param str1
         */
        private void getOffLineMsg(String str1) {
            LogManager.i("生成离线报警", str1);

        }

        /**
         * 获取设备的返回操作实时信息
         * @param result
         */
        private void getOperationMsg(String result) {
            LogManager.i("生成设备返回操作", result);
            if (result.equals("true")) {
                returnOper = true;
            } else {
                returnOper = false;
            }
        }


        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0) {

        }

        @Override
        public void connectionLost(Throwable arg0) {
            // 失去连接,重连
//            doClientConnection();
            LogManager.i("生成掉线", "mqtt掉线");
            if (arg0 != null) { //null表示被关闭
                startReconnectTask();
            }

        }
    };

    /**
     * 断线重连线程
     */
    private synchronized void startReconnectTask() {
        if (reconnectPool != null) return;
        reconnectPool = Executors.newScheduledThreadPool(1);
        reconnectPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                LogManager.i("生成重连", "mqtt重连");
                doClientConnection();
            }
        }, 20 * 1000, 5 * 1000, TimeUnit.MILLISECONDS);
    }

    /**
     * 关掉断线重连线程
     */
    private synchronized void closeReconnectTask() {
        if (reconnectPool != null) {
            reconnectPool.shutdownNow();
            reconnectPool = null;
        }
    }

    /**
     * 判断mqtt连接状态
     *
     * @return
     */
    public boolean isAlreadyConnected() {
        if (client != null) {
            try {
                boolean result = client.isConnected();
                if (result) {
                    return true;
                } else {
                    return false;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 判断网络是否连接
     */
    private boolean isConnectIsNormal() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null && info.isAvailable()) {
            String name = info.getTypeName();
            Log.i(TAG, "MQTT当前网络名称:" + name);
            return true;
        } else {
            Log.i(TAG, "MQTT 没有可用网络");
            return false;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(getClass().getName(), "onBind");
        return new CustomBinder();
    }

    /**
     * 开启服务
     */
    public static void startService(Context mContext) {
        mContext.startService(new Intent(mContext, MQTTService.class));
    }


    public void setIGetMessageCallBack(IGetMessageCallBack IGetMessageCallBack) {
        this.IGetMessageCallBack = IGetMessageCallBack;
    }

    public class CustomBinder extends Binder {
        public MQTTService getService() {
            return MQTTService.this;
        }
    }

//    @Override
//    public int onStartCommand(Intent intent, int flags, int startId) {
//        startNotificationForeground();
//        return START_STICKY;
//    }

    public interface IGetMessageCallBack {
        public void setMessage(String message);
    }


}

猜你喜欢

转载自blog.csdn.net/xiyangyang8110/article/details/126642276