Android -- MQTT协议

Android – MQTT协议

开篇

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。

MQTT 链接服务器

1.导入MQTT包:

    //导入mqtt包
    implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
    implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

2.MQTT管理类:

public class MQTTManager {
    public static final String SERVER_HOST = "tcp://##.##.###.###:####"; //使用自己的服务器地址名称
    private static final String TAG= "MQTTManager";
    private Context mContext;
    private static MQTTManager mqttManager=null;
    private MqttAndroidClient client;
    private MqttConnectOptions mMqttConnectOptions;
    private MessageHandlerCallBack callBack;
    private MTQQService mTQQService;
    private volatile BlockingDeque<BaseCommand> commandBlockingDeque;
    private boolean mIsBindService = false;
    public static String PUBLISH_TOPIC  = TopicData.TOPIC_UP;//发布主题
    public static String RESPONSE_TOPIC = LauncherApp.setIMEI();//订阅主题
    private MQTTManager (Context context){
        mContext=context;
    }
    /**
     * 获取一个MQTTManager单例
     * @param context
     * @return 返回一个MQTTManager的实例对象
     */
    public static MQTTManager getInstance(Context context) {
        UtilLog.i(TAG,"mqttManager="+mqttManager);
        if (mqttManager==null) {
            mqttManager=new MQTTManager(context);
            synchronized (Object.class) {
                UtilLog.i(TAG,"synchronized mqttManager="+mqttManager);
                if (mqttManager!=null) {
                    return mqttManager;
                }
            }
        }else {
            UtilLog.i(TAG,"else mqttManager="+mqttManager);
            return mqttManager;
        }
        return null;
    }
    /**
     * 订阅消息
     * @param topic 订阅消息的主题
     */
    public void subscribeMsg(String topic,int qos){
        if (client != null &&  client.isConnected()) {
            int[] Qos  = {qos};
            String[] topic1 = {topic};
            try {
                client.subscribe(topic1, Qos);
                UtilLog.i(TAG,"开始订阅topic="+topic);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }
    public void MQTTinit() {
        UtilLog.i(TAG, "---YMX------init() ----");
        UtilLog.i(TAG, "---YMX------init() -try ----");
        String serverURI = SERVER_HOST; //服务器地址(协议+地址+端口号)
        client = new MqttAndroidClient(mContext, serverURI, MTQQConstant.CLIENT);
        client.setCallback(mqttCallback); //设置监听订阅消息的回调
        mMqttConnectOptions = new MqttConnectOptions();
        mMqttConnectOptions.setCleanSession(true); //设置是否清除缓存
        mMqttConnectOptions.setConnectionTimeout(10*60); //设置超时时间,单位:秒
        mMqttConnectOptions.setKeepAliveInterval(5*60); //设置心跳包发送间隔,单位:秒
        mMqttConnectOptions.setUserName("admin"); //设置用户名
        mMqttConnectOptions.setPassword("password".toCharArray()); //设置密码
        boolean doConnect = true;
        if (doConnect) {
            UtilLog.i(TAG, "---YMX------doConnect() ----");
            doClientConnection();
        }
    }
        //订阅主题的回调
    private MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            UtilLog.i(TAG, "Client 接收消息主题 :------"+ topic);
            UtilLog.i(TAG, "Client 接收消息Qos-------"+ message.getQos());
            UtilLog.i(TAG, "Client 接收消息内容------ :"+ new String(message.getPayload()));
            String Data= new String(message.getPayload());
            UtilLog.i(TAG, "---YMX------mqttCallback ----Data----"+Data);
            ParseMTQQHelper.parse(Data);
          //  response("message arrived");
        }
        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
        }
        @Override
        public void connectionLost(Throwable arg0) {
            UtilLog.i(TAG, "---YMX------断开链接服务器 ----");
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    doClientConnection();//连接断开,重连
                    UtilLog.d(TAG, "---------IMqttActionListener------订阅"+RESPONSE_TOPIC+"---qos = --0---");
                }
            }, 10000);//3秒后执行Runnable中的run方法
        }
    };
        /**
     * 连接MQTT服务器
     */
    private void doClientConnection() {
        UtilLog.i(TAG, "---YMX------doClientConnection()开始链接服务器 ----");
        if (!client.isConnected() && isConnectIsNomarl()) {
            try {
                UtilLog.i(TAG, "---YMX------client.connect(mMqttConnectOptions) ----");
                client.connect(mMqttConnectOptions,null,iMqttActionListener);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }
     /**
     * 判断网络是否连接
     */
    private boolean isConnectIsNomarl() {
        ConnectivityManager connectivityManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null && info.isAvailable()) {
            String name = info.getTypeName();
            // Log.i(TAG, "当前网络名称:" + name);
            return true;
        } else {
            //  Log.i(TAG, "没有可用网络");
            /*没有可用网络的时候,延迟3秒再尝试重连*/
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    doClientConnection();
                }
            }, 30000);
            return false;
        }
    }
       //MQTT是否连接成功的监听
    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
        @Override
        public void onSuccess(IMqttToken arg0) {
            UtilLog.d(TAG, "---------IMqttActionListener-------------连接成功 ");
            if (RESPONSE_TOPIC!=null){
                subscribeMsg(RESPONSE_TOPIC, 0);
                AutoHrBtGpsUtil.getInstance().senStandard();
                UtilLog.d(TAG, "---------IMqttActionListener------订阅"+RESPONSE_TOPIC+"---qos = --0---");
            }else {
                UtilLog.d(TAG, "---------IMqttActionListener------订阅"+RESPONSE_TOPIC+"---为空执行延时操作-");
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                          RESPONSE_TOPIC= Util.getIMEI(LauncherApp.getAppContext());
                          subscribeMsg(RESPONSE_TOPIC, 0);
                          AutoHrBtGpsUtil.getInstance().senStandard();
                          UtilLog.d(TAG, "---------IMqttActionListener------订阅"+RESPONSE_TOPIC+"---qos = --0---");
                    }
                }, 3000);//3秒后执行Runnable中的run方法
            }
            UtilLog.d(TAG, "---------IMqttActionListener------订阅"+RESPONSE_TOPIC+"---qos = --0---");
        }
                @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            UtilLog.d(TAG, "连接失败 ");
            doClientConnection();//连接失败,重连(可关闭服务器进行模拟)
        }
    };
        /**
     * 发布消息
     * @param topic 发布消息主题
     * @param msg 消息体
     * @param isRetained 是否为保留消息
     */
    public void publish(String topic, base msg, boolean isRetained, int qos) {
        try {
            if (client!=null   &&  client.isConnected()) {
                Log.e(TAG, "publish:-------------YMX----------client "+ client );
                MqttMessage message = new MqttMessage();
                message.setQos(qos);
                message.setRetained(isRetained);
                message.setPayload(msg.toString().getBytes());
                client.publish(topic, message);
                UtilLog.i(TAG,"topic="+topic+"--msg="+msg.toString()+"--isRetained"+isRetained);
                }else if(client!=null   &&  !client.isConnected()){
                doClientConnection();
            }
        } catch (MqttPersistenceException e) {
            e.printStackTrace();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
        /**
     * 断开链接
     */
    public void disconnect(){
        UtilLog.i(TAG, "---YMX------disconnect: ----");
        if (client!=null &&client.isConnected()) {
            try {
                client.disconnect();
                mqttManager=null;
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }
        /**
     * 释放资源
     */
    public void release(){
        if (mqttManager!=null) {
            mqttManager=null;
        }
    }
    /**
     *  判断服务是否连接
     * @return
     */
    public boolean isConnected(){
        UtilLog.i(TAG, "---YMX------isConnected: ----");
        if (client!=null) {
            return client.isConnected();
        }
        return false;
    }  
}    

3.调用 MQTTinit() 方法就能实现链接服务器,订阅主题。

个人使用方案

  1. 个人项目是一个手表项目对接协议的。就直接在launcher中,写一个Service启动MQTTinit()方法,然后在Application的onCreate()方法中调用。

遇到的坑

1.mqtt协议频繁中断,频繁重连。
中断原因: clientld 重复。可以使用UUID生成随机数。 在这里插入图片描述
2。后续可能还会更新一些问题。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值