准备:
1.安装emqx
docker快速安装
docker run --restart=always -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.0.11
2.pom依赖
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
<version>5.5.13</version>
</dependency>
3.yml文件
mqtt:
open: true
#MQTT-服务器连接地址,如果有多个,用逗号隔开
host: tcp://192.168.20.3:1883
#MQTT-连接服务器默认客户端ID
clientId: mqtt_id
#MQTT-用户名
username: admin
#MQTT-密码
password: admin
#MQTT-默认的消息推送主题,实际可在调用接口时指定
topic: test
#连接超时
timeout: 1000
#设置会话心跳时间
keepalive: 100
springboot步骤
1.MqttConfig配置类,初始化客户端
//MQTT订阅
@Slf4j
@Configuration
@ConfigurationProperties("mqtt")
@Data
@Component
public class MqttConfig {
String host;
String clientId;
String topic;
String username;
String password;
Integer timeout;
Integer keepalive;
@Bean
@ConditionalOnProperty(prefix = "mqtt",name="open",havingValue = "true")
public MqttConnectOptions mqttConnectOptions() {
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(username);
options.setPassword(password.toCharArray());
options.setCleanSession(true);
options.setConnectionTimeout(timeout);
options.setKeepAliveInterval(keepalive);
return options;
}
@Bean
@ConditionalOnProperty(prefix = "mqtt",name="open",havingValue = "true")
public MqttClient mqttClient(MqttConnectOptions mqttConnectOptions) {
try {
MqttClient client = new MqttClient(host, clientId);
client.setCallback(new MessageCallback());
IMqttToken iMqttToken = client.connectWithResult(mqttConnectOptions);
boolean complete = iMqttToken.isComplete();
log.info("mqtt建立连接:{}", complete);
// 订阅主题
client.subscribe(topic, 0);
log.info("已订阅topic:{}", topic);
return client;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("mqtt 连接异常");
}
}
}
2.mqtt回调,用于接收消息
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.stereotype.Component;
/**
* consumer 消费者
*/
@Component
@Slf4j
public class MessageCallback implements MqttCallback {
@Autowired(required = false)
private MqttClient client;
@Override
public void connectionLost(Throwable throwable) {
if (client == null || !client.isConnected()) {
log.info("连接断开,正在重连....");
try {
client.connect();
if(client.isConnected()){
log.info("mqtt重连完成.");
}
} catch (MqttException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
log.info("接收消息主题 : " + topic);
log.info("接收消息内容 : " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
log.info("deliveryComplete---------" + token.isComplete());
}
}
3.mqtt工具类
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class MqttUtil {
@Autowired(required = false)
private MqttClient client;
/**
* 订阅主题
* @param topic
* @param qos
*/
public void subscribe(String topic, int qos) {
try {
client.subscribe(topic, qos);
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 订阅主题
* @param topic
*/
public void subscribe(String topic) {
try {
client.subscribe(topic);
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 发布消息
*
* @param qos 连接方式 0,1,2 默认0
*
* @param retained 是否保留最新的消息
* @param topic 订阅主题
* @param pushMessage 消息体
*/
public void publish(int qos, boolean retained, String topic, String pushMessage) {
MqttMessage message = new MqttMessage();
message.setQos(qos);
message.setRetained(retained);
message.setPayload(pushMessage.getBytes());
MqttTopic mqttTopic = client.getTopic(topic);
if (null == mqttTopic) {
log.error("topic not exist");
}
MqttDeliveryToken token;
try {
token = mqttTopic.publish(message);
token.waitForCompletion();
} catch (MqttPersistenceException e) {
e.printStackTrace();
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 发布消息
* @param topic 主题
* @param pushMessage 消息内容
*/
public void publish( String topic, String pushMessage) {
publish(0,true,topic,pushMessage);
}
}
4.测试
4.1 连接成功判断
4.2.发送消息
@RestController
@Slf4j
public class MqttController {
@Autowired
MqttClient client;
@Autowired
MqttUtil mqttUtil;
@GetMapping("/send")
public String send() {
try {
for (int i = 0; i < 3; i++) {
mqttUtil.publish("test","消息hello"+i);
log.info("发送成功:{}", i);
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
return "SUCCESS";
}
}