成果有参考网上各位大拿的分享代码,在此先行谢过。
难点我觉得在于两点,一个是MQTT运行过程中链接丢失如何重连,另一个是MQTT第一次连接的时候就失败如何重连,
话不多说直接上代码:
package com.jinhui.pdmplatform.appointmentsync.controller;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.annotation.PostConstruct;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.jinhui.pdmplatform.Constants;
import com.jinhui.pdmplatform.appointmentsync.service.IAppointmentService;
import com.jinhui.pdmplatform.control.controlmanager.controller.PushCallback;
/**
*
* @author duanqm ReceiveMQTT 2019年7月11日下午4:24:26
*/
@Controller
public class ReceiveMQTT {
@Autowired
private IAppointmentService appointmentService; // 静态方法service 注入方法
private static ReceiveMQTT receiveMQTT;
// 静态方法service 注入方法
@PostConstruct
public void init() {
receiveMQTT = this;
receiveMQTT.appointmentService = this.appointmentService;
}
private static Logger logger = Logger.getLogger(ReceiveMQTT.class);
public static Map<String, Integer> alarmInfoMap = new HashMap<String, Integer>();
private static int qos = 0;
private static String serverURI = Constants.YUN_MQTT_HOST;
private static String admin = Constants.YUN_MQTT_userName;
private static String password = Constants.YUN_MQTT_Password;
private static String clientid = UUID.randomUUID().toString()
.replace("-", "");
private static String appointment_topic = Constants.YUN_APPOINTMENT_MQTT_TOPIC;
private static MqttClient mqttClient;
/**
* 项目启动执行MQTT
*/
public void run() {
try {
if (mqttClient == null) {
mqttClient = connect(clientid);
logger.info("mqtt连接成功");
}
} catch (Exception e) {
e.printStackTrace();
logger.error("mqtt连接异常," + e.getMessage());
}
// 订阅消息
if (mqttClient != null && mqttClient.isConnected()) { // 连接中
try {
doSub(appointment_topic);
} catch (MqttException e) {
e.printStackTrace();
logger.error("接收mqtt消息失败," + e.getMessage());
}
}
}
/**
* 连接mqtt
*
* @param clientId
* @return
* @throws MqttException
*/
private static MqttClient connect(String clientId) throws MqttException {
MemoryPersistence persistence = new MemoryPersistence();
MqttConnectOptions connOpts = new MqttConnectOptions();
// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
connOpts.setCleanSession(false);
// 设置连接的用户名
connOpts.setUserName(admin);
// 设置连接的密码
connOpts.setPassword(password.toCharArray());
connOpts.setConnectionTimeout(10);
connOpts.setKeepAliveInterval(20);
connOpts.setAutomaticReconnect(true);// 设置自动重连
if (mqttClient == null) {
mqttClient = new MqttClient(serverURI, clientId, persistence);
}
// 连接丢失后的断线重连
mqttClient.setCallback(new PushCallback() {
public void connectionLost(Throwable cause) {
// 连接丢失后,一般在这里面进行重连
logger.info("[MQTT] 连接断开,30S之后尝试重连...");
while (true) {
try {
Thread.sleep(30000);
connect(clientid);
doSub(appointment_topic);
break;
} catch (Exception e) {
// e.printStackTrace();
continue;
}
}
}
});
// 第一次连接就失败,重连机制
try {
if (!mqttClient.isConnected()) {
mqttClient.connect(connOpts);
}
} catch (Exception e) {
e.printStackTrace();
logger.error("mqtt连接失败");
for (int i = 0; i < 999; i++) {
try {
Thread.sleep(3000);
mqttClient.connect(connOpts);
logger.info("mqtt连接成功");
break;
} catch (Exception e1) {
// e1.printStackTrace();
int k = i + 1;
logger.error("mqtt连接失败,正在第" + k + "次尝试");
continue;
}
}
}
return mqttClient;
}
/**
* 订阅消息方法
*
* @param mqttClient
* @param topic
* @throws MqttException
*/
public static void sub(MqttClient mqttClient, String topic)
throws MqttException {
int[] Qos = { qos };
String[] topics = { topic };
mqttClient.subscribe(topics, Qos);
}
/**
* 执行订阅
*
* @param topic
* @throws MqttException
*/
private static void doSub(String topic) throws MqttException {
if (mqttClient.isConnected()) {
sub(mqttClient, topic);
}
mqttClient.subscribe(topic, 0, new IMqttMessageListener() {
// 回掉函数
@Override
public void messageArrived(String topic, MqttMessage message)
throws Exception {
// TODO Auto-generated method stub
try {
String info = new String(message.getPayload());
JSONObject json = JSONObject.fromObject(info);
Long realtime = (Long) json.get("realtime");
if (realtime != null) {
logger.info("-------接收消息-------时间戳:" + realtime);
logger.info("------------------------");
logger.info("------------------------");
logger.info("MQTT执行访客预约同步任务开始...");
boolean flag = receiveMQTT.appointmentService
.AppointmentSync();
if (flag) {
logger.debug("同步成功");
// 执行存储过程同步jh_controlpeople的picpath至jh_appointment中
int num = receiveMQTT.appointmentService
.fun_update_appointment();
if (num == 1) {
logger.info("成功将jh_controlpeople的picpath值同步至jh_appointment中");
}
} else {
logger.debug("同步失败");
}
logger.info("MQTT执行访客预约同步任务结束...");
logger.info("------------------------");
logger.info("------------------------");
}
} catch (Exception e) {
logger.error("MQTT执行访客预约同步任务发生异常");
e.printStackTrace();
}
}
});
}
}