springboot mqtt
pom
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
MqttConfig
package com.zucc.eye.mqtt;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@Configuration
@PropertySource("classpath:application.yml")
//指明配置文件位置 会自动去resouces下找到此文件
//@ConfigurationProperties(prefix = "mqtt")
//添加一个 配置,万一要改 只要在这里改就好了,集中在一起,比较方便
@Data
public class MqttConfig {
@Value("${mqtt.host}")
public static String MQTT_HOST ;
@Value("${mqtt.client_id}")
public static String MQTT_CLIENT_ID ;
@Value("${mqtt.username}")
public static String MQTT_USERNAME ;
@Value("${mqtt.password}")
public static String MQTT_PASSWORD ;
//要写在 set
@Value("${mqtt.host}")
public void setMQTT_HOST(String mqttHost) {
MQTT_HOST = mqttHost;
}
@Value("${mqtt.client_id}")
public void setMQTT_CLIENT_ID(String mqtt_client_id) {
MQTT_CLIENT_ID = mqtt_client_id;
}
@Value("${mqtt.username}")
public void setMQTT_USERNAME(String mqtt_username) {
MQTT_USERNAME = mqtt_username;
}
@Value("${mqtt.password}")
public void setMQTT_PASSWORD(String mqtt_password) {
MQTT_PASSWORD = mqtt_password;
}
//@Bean
public MqttConfig() {
}
public static void main(String[] args) {
}
}
package com.zucc.eye.mqtt;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* MQTT 推送回调
*/
//@Slf4j
public class PushCallback implements MqttCallback {
private MqttClient client;
private MqttConnectOptions options;
private static final Logger log = LoggerFactory.getLogger(PushCallback.class);
public PushCallback(MqttClient client, MqttConnectOptions options) {
this.client = client;
this.options = options;
}
@SneakyThrows
@Override
public void connectionLost(Throwable cause) {
// log.info("断开连接,建议重连" + this);
log.warn("断开连接,建议重连");
log.warn("原因: " + cause);
//断开连接,重连
int tryTimes = 1;
while (!client.isConnected()) {
Thread.sleep(1000);
log.info("重试第{}次", tryTimes);
// https://blog.csdn.net/zhan107876/article/details/100935779
//即使连接上也要先断开再重新连接
// client.disconnect(); //不这样就重连会报错
// 这里不能断开连接啊,断了就有问题
// log.info("重新连接");
client.connect(options);
log.info("连接完成");
tryTimes++;
}
log.info("重连成功,开始订阅消息");
//发布相关的订阅
// 订阅
String[] topic = {"SysInit", "xx", "xx", "xx", "xx"};
int[] qos = {1, 1, 1, 1, 1};
client.subscribe(topic, qos);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
//log.info(token.isComplete() + "");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
// log.info("Topic: " + topic);
// log.info("Message: " + new String(message.getPayload()));
JSONObject jsonObject = JSONObject.parseObject(new String(message.getPayload()));
PushClient client = PushClient.getInstance();
if (topic.equals("SysInit")) {
}
}
Double getDoubleFromJSONObject(JSONObject jsonObject, String key) {
try {
return jsonObject.getBigDecimal(key).doubleValue();
} catch (Exception e) {
try{
return Double.parseDouble(jsonObject.getString(key));
}catch (Exception e1){
return null;
}
}
}
}
package com.zucc.eye.mqtt;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 创建一个MQTT客户端
*/
public class PushClient {
private static final Logger log = LoggerFactory.getLogger(PushClient.class);
public static String MQTT_HOST = "";
public static String MQTT_CLIENTID = "";
public static String MQTT_USERNAME = "";
public static String MQTT_PASSWORD = "";
public static int MQTT_KEEPALIVE = 10;
private MqttClient client;
private static volatile PushClient mqttClient = null;
public static PushClient getInstance() {
initConfig();
// 2021年8月3日16:09:13 mqp host 在获取 instance的时候要获取
if (mqttClient == null) {
synchronized (PushClient.class) {
if (mqttClient == null) {
mqttClient = new PushClient();
}
}
}
return mqttClient;
}
private static void initConfig() {
PushClient.MQTT_HOST = MqttConfig.MQTT_HOST;
PushClient.MQTT_CLIENTID = MqttConfig.MQTT_CLIENT_ID;
PushClient.MQTT_USERNAME = MqttConfig.MQTT_USERNAME;
PushClient.MQTT_PASSWORD = MqttConfig.MQTT_PASSWORD;
}
PushClient() {
log.info("Connect MQTT: " + this);
connect();
}
private void connect() {
try {
client = new MqttClient(MQTT_HOST, MQTT_CLIENTID, new MemoryPersistence());
MqttConnectOptions option = new MqttConnectOptions();
option.setCleanSession(true);
// option.setCleanSession(false);
option.setUserName(MQTT_USERNAME);
option.setPassword(MQTT_PASSWORD.toCharArray());
option.setConnectionTimeout(0);
option.setKeepAliveInterval(MQTT_KEEPALIVE);
option.setAutomaticReconnect(true);
try {
client.setCallback(new PushCallback(client, option));
client.connect(option);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发布主题,用于通知<br>
* 默认qos为1 非持久化
*
* @param topic
* @param data
*/
public void publish(String topic, String data) {
publish(topic, data, 1, false);
}
/**
* 发布
*
* @param topic
* @param data
* @param qos
* @param retained
*/
public void publish(String topic, String data, int qos, boolean retained) {
MqttMessage message = new MqttMessage();
message.setQos(qos);
message.setRetained(retained);
message.setPayload(data.getBytes());
MqttTopic mqttTopic = client.getTopic(topic);
if (null == mqttTopic) {
log.error("Topic Not Exist");
}
MqttDeliveryToken token;
try {
token = mqttTopic.publish(message);
token.waitForCompletion();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 订阅某个主题 qos默认为1
*
* @param topic
*/
public void subscribe(String topic) {
subscribe(topic, 0);
}
/**
* 订阅某个主题
*
* @param topic
* @param qos
*/
public void subscribe(String topic, int qos) {
try {
client.subscribe(topic, qos);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// MqttConfig mqttConfig = new MqttConfig();
//不能靠 new
// PushClient.MQTT_HOST = mqttConfig.getMQTT_HOST();
// PushClient.MQTT_CLIENTID = mqttConfig.getMQTT_CLIENT_ID();
// PushClient.MQTT_USERNAME = mqttConfig.getMQTT_USERNAME();
// PushClient.MQTT_PASSWORD = mqttConfig.getMQTT_PASSWORD();
PushClient.MQTT_HOST = MqttConfig.MQTT_HOST;
PushClient.MQTT_CLIENTID = MqttConfig.MQTT_CLIENT_ID;
PushClient.MQTT_USERNAME = MqttConfig.MQTT_USERNAME;
PushClient.MQTT_PASSWORD = MqttConfig.MQTT_PASSWORD;
PushClient client = PushClient.getInstance();
// client id不能和 mqttx的一样,client_id 自己造一个就行
System.out.println("订阅");
client.subscribe("SysInit");
client.subscribe("xx");
client.subscribe("xx");
client.subscribe("xxx");
// 这里连了 mqttx 就断开了
System.out.println("发送");
client.publish("xxx", "java send");
}
}
mqtt:
host: "tcp://localhost:1883"
client_id: xxx
username: xxx
password: xxx