springboot项目集成mqtt订阅信息websoket推送
pom.xml
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
yml
server:
port: 8810
spring:
application:
name: dp-alarm
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://ip:3306/database?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC
username: root
password: password
type: com.zaxxer.hikari.HikariDataSource
mvc:
static-path-pattern: /**
mqtt:
url: tcp://ip:1883
username: root
password: root
topic: lbmqtt
# qos: 1 # QoS 级别
# keep-alive-interval: 60 # 心跳间隔(秒)
# connection-timeout: 10
logging:
level:
org.springframework.jdbc.core.JdbcTemplate: DEBUG
data:
type: MBTCP_D1
MosquittoMQTT
package com.dp.utils.mqtt;
import com.dp.service.UpService;
import com.dp.utils.io.ENS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
/**
* Created by lenovo on 2022/11/9.
*/
@Component
@EnableAsync
public class MosquittoMQTT implements ApplicationRunner {
@Autowired
UpService upService;
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
mqttClient();
}
@Value("${mqtt.url}")
private String url;
@Value("${mqtt.username}")
private String username;
@Value("${mqtt.password}")
private String password;
@Value("${mqtt.topic}")
private String topic;
@Value("${data.type}")
private String type;
@Async
public void mqttClient(){
String clientID = ENS.getUUID();;
int qos = 1;
System.out.println(url+username+password);
MqttSubscriber mqttSubscriber = new MqttSubscriber(url,clientID,username,password,type);
mqttSubscriber.subscribe(upService,topic,qos,username,password,type);
}
}
MqttSubscriber
package com.dp.utils.mqtt;
import com.alibaba.fastjson.*;
import com.dp.service.UpService;
import com.dp.utils.enmu.CommonEnum;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
/**
* Created by lenovo on 2022/11/2.
*/
public class MqttSubscriber {
private String type;
private String username;
private String password;
private MqttClient mqttClient;
public MqttSubscriber(String SERVER_URI, String CLIENT_ID, String username, String password,String type) {
try {
this.type = type;
this.username = username;
this.password = password;
MemoryPersistence persistence = new MemoryPersistence();
mqttClient = new MqttClient(SERVER_URI, CLIENT_ID, persistence);
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(false);//false
connOpts.setUserName(username);
connOpts.setPassword(password.toCharArray());
connOpts.setConnectionTimeout(30);
connOpts.setKeepAliveInterval(60);
connOpts.setAutomaticReconnect(true);
mqttClient.connect(connOpts);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void subscribe(UpService upService, String topic, int qos,String username,String password,String type) {
this.type = type;
if (mqttClient == null) {
return;
}
try {
mqttClient.subscribe(topic, qos);
mqttClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable throwable) {
System.out.println("连接丢失,丢失原因为:"+throwable.getMessage());
CommonEnum.isconn = true;
// 使用循环重试,避免单次失败后停止
new Thread(() -> {
int retryCount = 0;
while (true) {
try {
// 每次重连前先断开旧连接(防止状态残留)
if (mqttClient != null && mqttClient.isConnected()) {
try {
mqttClient.disconnect();
} catch (Exception e) {
System.out.println("断开旧连接失败:" + e.getMessage());
}
}
// 重新设置连接参数(复用原构造函数中的配置,避免默认参数问题)
if (mqttClient == null) {
System.out.println("mqttClient 为空,无法重连");
break;
}
// 重新连接(使用原连接选项,需在 MqttSubscriber 中保存 connOpts)
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName(username); // 需在 MqttSubscriber 中保存 username 字段
connOpts.setPassword(password.toCharArray()); // 保存 password 字段
connOpts.setConnectionTimeout(10);
connOpts.setKeepAliveInterval(20);
connOpts.setAutomaticReconnect(true);
mqttClient.connect(connOpts);
mqttClient.subscribe(topic, qos); // 重新订阅主题
System.out.println("MQTT 重连成功!");
retryCount = 0; // 重置重试计数
break; // 重连成功后退出循环
} catch (Exception e) {
retryCount++;
// 指数退避重试(避免频繁重试导致服务器压力)
long sleepTime = Math.min(1000 * (1 << retryCount), 30000); // 1s, 2s, 4s... 最大30s
System.out.println("第 " + retryCount + " 次重连失败," + sleepTime + "ms 后重试:" + e.getMessage());
e.printStackTrace();
try {
Thread.sleep(sleepTime);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
break;
}
}
}
}).start();
}
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
// String str = new String(mqttMessage.getPayload(),"GB2312").replaceAll("\\s", "");
String str = new String(mqttMessage.getPayload(),StandardCharsets.UTF_8).replaceAll("\\s", "");
// List<Map<String,Object>> list = new ArrayList<>();
try {
// List<Map<String,Object>> list1 = (List<Map<String, Object>>) JSON.parse(str);
Map<String,Object> map = (Map<String, Object>) JSON.parse(str);
Map<String,Object> map1 = (Map<String, Object>) map.get("data");
// 禹王:ZDWXY_D1
// 瑞赛科:MBTCP_D1
List<Map<String, Object>> list1 = (List<Map<String, Object>>)map1.get(type);
Data data = SpringContextUtil.getDataInstance();
data.setLs(list1);
} catch (Exception e) {
System.out.println("数据转换异常");
e.printStackTrace();
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println("delivery isComplete:" + iMqttDeliveryToken.isComplete());
}
});
} catch (MqttException e) {
System.out.println(e.getMessage());
}
}
public void disconnect() {
if (mqttClient != null && mqttClient.isConnected()) {
try {
mqttClient.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
}
}
SpringContextUtil
package com.dp.utils.mqtt;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author LLF
* @title SpringContextUtil
* @date 2025/10/16 19:15
* @description TODO
*/
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
applicationContext = context;
}
// 静态方法:获取 Data 实例
public static Data getDataInstance() {
return applicationContext.getBean(Data.class);
}
}
Data
package com.dp.utils.mqtt;
import com.dp.service.UpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author LLF
* @title Data
* @date 2025/10/16 16:46
* @description TODO
*/
@Component
@EnableAsync
public class Data {
@Autowired
private UpService upService;
private List<Map<String, Object>> ls = new CopyOnWriteArrayList<>();
public Data(){
this.ls = new CopyOnWriteArrayList<>();
}
@Scheduled(cron = "0/10 * * * * ?")
@Async
public void insertData() {
try {
if (ls != null && !ls.isEmpty()) {
upService.saveData(ls);
ls.clear();
}else{
System.out.println("保存数据为空:"+ls);
}
} catch (Exception e) {
System.out.println("保存数据失败,原因如下:");
e.printStackTrace();
}
}
public void setLs(List<Map<String, Object>> newLs) {
if (newLs != null && !newLs.isEmpty()) {
ls = newLs;
}
}
public List<Map<String, Object>> getLs() {
return ls;
}
}

浙公网安备 33010602011771号