最近在使用MQTT来实现消息的传输,网上demo很多,这里就不在重复介绍了,直接上代码,百度就能出现一大堆

  下面是MQTT实现订阅的主要代码部分

  

MqttClient client = new MqttClient(HOST, clientid, new MemoryPersistence());

MqttConnectOptions options = new MqttConnectOptions();

options.setCleanSession(true);

options.setUserName(userName);

options.setPassword(passWord.toCharArray());

options.setConnectionTimeout(10);

options.setKeepAliveInterval(20);
//设置断开后重新连接
options.setAutomaticReconnect(true); try { client.setCallback(new PushCallback());//设置各种情况的回调函数 client.connect(options); //订阅消息
int[] Qos = {0}; String[] topic1 = {TOPIC}; client.subscribe(topic1, Qos); } catch (Exception e) { e.printStackTrace(); }

回到方法实现代码如下

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic; public class PushCallback implements MqttCallback {
public void connectionLost(Throwable cause) { // 连接丢失后,触发这个方法 } @Override
public void deliveryComplete(IMqttDeliveryToken token) {
// publish后会执行到这里 }
@Override
public void messageArrived(String arg0, MqttMessage arg1) throws Exception {
System.out.println("接收消息主题:"+arg0); System.out.println("接收消息Qos:"+arg1.getQos()); System.out.println("接收消息内容:"+new String(arg1.getPayload())); }
}

  如果MQTT连接断开,会调用connectionLost 函数,我一开始觉得直接在这里使用client.connect(options),就可以直接实现重连了,结果报错mqtt的状态为

这个好解决,如果这样设置,可以实现断开自动重连

//设置断开后重新连接
options.setAutomaticReconnect(true);

但这样重连是实现了,但是之前订阅的主题却接收不到消息了,需要重新订阅主题才能正常接收消息,那我这个重新订阅的代码要怎么再放进去呢,反正不是再connectionLost里就是了,那是后连接还没有重连连上!

继续看MQTT的connec的源码发现了一段代码使我找到了解决方案

MqttReconnectCallback 是实现MqttCallbackExtended接口的

发现comms中有设置重连的回调对象,但是怎么把这个回调由我们来主动放进去呢?继续往下看源码可以发现

也就是如果我们在之前放入client的回调对象是实现的 MqttCallbackExtended 接口,则MQTT会将我们的回调对象放入 connectActionListener 中 然后由 connectActionListener实现具体的connect

接下来我们不callback 对象改为实现 MqttCallbackExtended这个接口,然后实现下面方法,

@Override
public void connectComplete(boolean reconnect, String serverURI) {
//连接成功后调用
      client.subscribe(topics,Qos);//具体订阅代码
}

  

就可以解决MQTT重连后无法订阅的问题

使用paho的MQTT时遇到的重连导致订阅无法收到问题和解决的更多相关文章

  1. Paho -物联网 MQTT C Cient的实现和详解

    概述   在文章Paho - MQTT C Cient的实现中,我介绍了如何使用Paho开源项目创建MQTTClient_pulish客户端.但只是简单的介绍了使用方法,而且客户端的结果与之前介绍的并 ...

  2. MQTT的学习研究(十四) MQTT moquette 的 Callback API 消息发布订阅的实现

    在moquette-mqtt中提供了回调callback模式的发布和订阅但是在订阅之后没有发现有消息接收的方法,参看moquette-mqtt中Block,Future式的发布订阅基础是callbac ...

  3. MQTT的学习研究(十二) MQTT moquette 的 Future API 消息发布订阅的实现

    MQTT moquette 的Server发布主题 package com.etrip.mqtt.future; import java.net.URISyntaxException; import  ...

  4. Sqlserver2005附加数据库时出错提示操作系统错误5(拒绝访问)错误5120的解决办法

    Sqlserver2005附加数据库时出错提示操作系统错误5(拒绝访问)错误5120的解决办法 最近几天从网上找了几个asp.net的登录案例想要研究研究代码,结果在用 Sql Server2005附 ...

  5. 运行WampServer时,提示Exception Exception in module wampmanager.exe at 000F15A0.解决办法

    出现问题:运行WampServer时,提示Exception Exception in module wampmanager.exe at 000F15A0.解决办法 出现问题原因: ①:缺少Visu ...

  6. SQLServer2005+附加数据库时出错提示操作系统错误5(拒绝访问)错误5120的解决办法

    SQLServer2005+ 附加数据库时出错提示操作系统错误5(拒绝访问)错误5120的解决办法 我们在用Sql SQLServer2005+附加数据库文件时弹出错误信息如下图的处理办法: 方案一: ...

  7. Django中上传图片---避免因图片重名导致被覆盖

    上一篇文章中(https://www.cnblogs.com/lutt/p/10640412.html),我们以图片文件夹+图片名字的方式来储存图片,这样的做法会导致有重名的图片会导致之前的图片被覆盖 ...

  8. [经使用有效]Sqlserver2005附加数据库时出错提示操作系统错误5(拒绝访问)错误5120的解决办法

    sqlserver2005附加数据库时出错提示操作系统错误5(拒绝访问)错误5120的解决办法 最近几天从网上找了几个asp.net的登录案例想要研究研究代码,结果在用 Sql Server2005附 ...

  9. windows使用git时出现:warning: LF will be replaced by CRLF的解决办法

    在Windows环境下使用git进行add的时候,会提示如下warning: “warning:LF will be replacee by CRLF”. 这是因为在Windows中的换行符为CRLF ...

随机推荐

  1. 【Flutter 实战】pubspec.yaml 配置文件详解

    老孟导读:pubspec.yaml 文件是 Flutter 中非常重要的配置文件,下面就让我们看看里面各个配置的含义. pubspec.yaml 是 Flutter 项目的配置文件,类似于 Andro ...

  2. POJ2430 Lazy Cows

    题意描述 Lazy Cows 给定一个 \(2\times b\) 的矩形,和 \(n\) 个矩形上的点. 要求你用 \(k\) 个矩形覆盖这 \(n\) 个点,使得每个点都被覆盖的前提下这些矩形的面 ...

  3. leetcode两数之和go语言

    两数之和(Go语言) 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复 ...

  4. JavaScript的原型对象prototype、原型属性__proto__、原型链和constructor

    先画上一个关系图: 1. 什么是prototype.__proto__.constructor? var arr = new Array; 1. __proto__是原型属性,对象特有的属性,是对象指 ...

  5. python00

    # Python* [什么是 Python 生成器?](#什么是-Python-生成器)* [什么是 Python 迭代器?](#什么是-Python-迭代器)* [list 和 tuple 有什么区 ...

  6. MySql Binlog 说明 & Canal 集成MySql的更新异常说明 & MySql Binlog 常用命令汇总

    文章来源于本人的印象笔记,如出现格式问题可访问该链接查看原文 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录 背景介绍 开启MySq ...

  7. strace 使用文档

    strace -c 统计每一系统调用的所执行的时间,次数和出错的次数等. -d 输出strace关于标准错误的调试信息. -f 跟踪由fork调用所产生的子进程. -ff 如果提供-o filenam ...

  8. 极客mysql13

    1:为啥删除了表的一半数8据,表文文件大小没变化?因为delete 命令其实只是把记录的位置,或者数据页标记为了"可复用",但磁盘文件的大小是不会变的.也可以认为是一种逻辑删除,所 ...

  9. mysql mybatis Date java时间和写入数据库时间不符差一秒问题

    1,java的数据库实体定义 private Timestamp createTime:2,非常重要!ddl语句建表字段的单位 datetime要手动设置保留3位毫秒数,不然就四舍五入了! ALTER ...

  10. 面试常问的 25+ 个 Linux 命令

    作为一个Java开发人员,有些常用的Linux命令必须掌握.即时平时开发过程中不使用Linux(Unix)或者mac系统,也需要熟练掌握Linux命令.因为很多服务器上都是Linux系统.所以,要和服 ...