消息发布参考:https://blog.csdn.net/weixin_42360600/article/details/123227626
1、准备环境
本地启动 Mqtt服务器
新建Springboot项目作为消费端
2、pom引入mqtt依赖
<!-- mqtt -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
3、application.properties配置mqtt参数
server.port=8082
#MQTT配置信息
#MQTT-用户名
spring.mqtt.username=admin
#MQTT-密码
spring.mqtt.password=password
#MQTT-服务器连接地址,如果有多个,用逗号隔开,如:tcp://127.0.0.1:61613,tcp://47.123.33.66:61613
spring.mqtt.url=tcp://127.0.0.1:61613
#MQTT-连接服务器默认客户端ID
spring.mqtt.client.id=maqttReceive
#MQTT-默认的消息推送主题,实际可在调用接口时指定
spring.mqtt.default.topic=test
#timeout 链接超时时间
mqtt.connection.timeout=20
#keep alive
mqtt.keep.alive.interval=20
4、MqttClient 启动项目链接mqtt服务器,定义callback回调函数
@Component
@Slf4j
public class MqttClientUtil {
@Value("${spring.mqtt.username}")
private String username;
@Value("${spring.mqtt.password}")
private String password;
@Value("${spring.mqtt.url}")
private String host;
@Value("${spring.mqtt.client.id}")
private String clientId;
@Value("${spring.mqtt.default.topic}")
private String topic;
@Value("${mqtt.connection.timeout}")
private int timeOut;
@Value("${mqtt.keep.alive.interval}")
private int interval;
@Autowired
private MqttMessageCallback mqttMessageCallback;
private MqttClient mqttClient;
private MqttConnectOptions mqttConnectOptions;
@PostConstruct
private void init(){
connect(host, clientId,topic);
}
/**
* 链接mqtt
* @param host
* @param clientId
*/
private void connect(String host,String clientId,String topic){
try{
mqttClient = new MqttClient(host,clientId,new MemoryPersistence());
mqttConnectOptions = getMqttConnectOptions();
//设置回调函数
mqttClient.setCallback(mqttMessageCallback);
//链接mqtt
mqttClient.connect(mqttConnectOptions);
//订阅消息
mqttClient.subscribe(topic,2);
}catch (Exception e){
log.error("mqtt服务链接异常!");
e.printStackTrace();
}
}
/**
* 设置链接对象信息
* setCleanSession true 断开链接即清楚会话 false 保留链接信息 离线还会继续发消息
* @return
*/
private MqttConnectOptions getMqttConnectOptions(){
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setUserName(username);
mqttConnectOptions.setPassword(password.toCharArray());
mqttConnectOptions.setServerURIs(new String[]{host});
mqttConnectOptions.setKeepAliveInterval(interval);
mqttConnectOptions.setConnectionTimeout(timeOut);
mqttConnectOptions.setCleanSession(true);
return mqttConnectOptions;
}
/**
*mqtt链接状态
* @return
*/
private boolean isConnect(){
if(Objects.isNull(this.mqttClient)){
return false;
}
return mqttClient.isConnected();
}
/**
* 设置重连
* @throws Exception
*/
private void reConnect() throws Exception{
if(Objects.nonNull(this.mqttClient)){
log.info("mqtt 服务已重新链接...");
this.mqttClient.connect(this.mqttConnectOptions);
}
}
/**
* 断开链接
* @throws Exception
*/
private void closeConnect() throws Exception{
if(Objects.nonNull(this.mqttClient)){
log.info("mqtt 服务已断开链接...");
this.mqttClient.disconnect();
}
}
/**
* 发布消息
* @param topic
* @param message
* @param qos
* @throws Exception
*/
public void sendMessage(String topic,String message,int qos) throws Exception {
if(Objects.nonNull(this.mqttClient) && this.mqttClient.isConnected()){
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setPayload(message.getBytes());
mqttMessage.setQos(qos);
MqttTopic mqttTopic = mqttClient.getTopic(topic);
if(Objects.nonNull(mqttTopic)){
try{
MqttDeliveryToken publish = mqttTopic.publish(mqttMessage);
if(publish.isComplete()){
log.info("消息发送成功---->{}",message);
}
}catch(Exception e){
log.error("消息发送异常",e);
}
}
}else{
reConnect();
}
}
}
@Component
@Slf4j
public class MqttMessageCallback implements MqttCallback {
/**
* 链接丢失时处理
* @param throwable
*/
@Override
public void connectionLost(Throwable throwable) {
//可以做重连 或者 其他业务处理
}
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
log.info("接收到消息topic---->{}",topic);
log.info("接收到消息质量qos---->{}",mqttMessage.getQos());
log.info("接收到消息具体信息---->{}",new String(mqttMessage.getPayload()));
//结合业务 编写具体信息即可
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
}
5、测试
启动消息生产者服务,发布消息
启动消息接收者服务,接收消息
注意:clientId 不要相同,topic要保持一致