介绍
MQTT 是一种基于发布/订阅模式的轻量级消息传输协议,专门针对低带宽和不稳定网络环境的物联网应用而设计,可以用极少的代码为联网设备提供实时可靠的消息服务。MQTT 协议广泛应用于物联网、移动互联网、智能硬件、车联网、智慧城市、远程医疗、电力、石油与能源等领域。
MQTT 协议由 Andy Stanford-Clark (IBM)和 Arlen Nipper(Arcom,现为 Cirrus Link)于 1999 年发布。 按照 Nipper 的介绍,MQTT 必须具备以下几点:
简单容易实现
支持 QoS(设备网络环境复杂)
轻量且省带宽(因为那时候带宽很贵)
数据无关(不关心 Payload 数据格式)
有持续地会话感知能力(时刻知道设备是否在线)
————————————————
依赖
<!--MQTT 链接 -->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
</dependency>
MQTT推动服务
package com.kuangan.mqtt;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.stereotype.Service;
import java.util.UUID;
@Slf4j
@Service
public class MqttClientService {
private MqttClient client;
/**
* 连接到MQTT代理服务器
*
* @throws MqttException
*/
@PostConstruct
public void connect() throws MqttException {
String broker = "tcp://127.0.0.1:1883";
String clientId = UUID.randomUUID();
client = new MqttClient(broker, clientId);
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(false);
options.setUserName("admin");
options.setPassword("123456".toCharArray());
options.setKeepAliveInterval(120);
options.setAutomaticReconnect(true);
client.connect(options);
log.info("MQTT链接成功服务器地址{},客户端id:{}", broker, clientId);
}
/**
* 发送mqtt消息
*/
public Boolean sendMsg(String msg,String topi1cName){
int qos = 1;
MqttMessage mqttMessage = new MqttMessage(msg.getBytes());
mqttMessage.setQos(qos);
try {
client.publish(topi1cName, mqttMessage);
return true;
} catch (MqttException e) {
e.printStackTrace();
return false;
}
}
/**
* 订阅主题并设置消息监听器
*
* @param topic 要订阅的主题
* @param listener 消息监听器
* @throws MqttException
*/
public void subscribe(String topic, IMqttMessageListener listener) throws MqttException {
client.subscribe(topic, listener);
}
/**
* 断开与MQTT代理服务器的连接
*
* @throws MqttException
*/
public void disconnect() throws MqttException {
client.disconnect();
}
/**
* 断开与topic
*
* @throws MqttException
*/
public void unsubscribe(String topic) throws MqttException {
client.unsubscribe(topic);
}
}
MQTT监听服务
package com.kuangan.other.mqtt;
import com.kuangan.common.core.domain.R;
import com.kuangan.common.json.utils.JsonUtils;
import com.kuangan.mine.domain.MineSlopeLog;
import com.kuangan.mine.mapper.MineSlopeLogMapper;
import com.kuangan.mqtt.MqttClientService;
import com.kuangan.other.constant.MqttConstant;
import jakarta.annotation.Resource;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
@Component
public class MqttSubscriberListener implements MqttCallback {
private final MqttClient client;
@Resource
private MqttClientService mqttClientService;
public MqttSubscriberListener() throws MqttException {
String broker = "tcp://127.0.0.1:1883";
String clientId = UUID.randomUUID();;
client = new MqttClient(broker, clientId);
client.setCallback(this);
connect();
subscribe();
}
private void connect() throws MqttException {
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
// 设置认证信息
// connOpts.setUserName("yourUsername");
// connOpts.setPassword("yourPassword".toCharArray());
client.connect(connOpts);
}
/**
* 订阅主题--OF_SEN_POS
*
* @throws MqttException
*/
private void subscribe() throws MqttException {
client.subscribe(MqttConstant.OF_SEN_POS);
}
@Override
public void connectionLost(Throwable cause) {
// 连接丢失后的处理逻辑
System.out.println("Connection lost");
try {
connect();
} catch (MqttException e) {
e.printStackTrace();
}
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
// 接收到消息的处理逻辑
if (new String(message.getPayload()).equals(MqttConstant.OF_SEN_POS)){
List<MineSlopeLog> mineSlopeLogs = new ArrayList<>();
mqttClientService.sendMsg(Objects.requireNonNull(JsonUtils.toJsonString(mineSlopeLogs)),MqttConstant.OF_SEN_POS);
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// 消息发送成功的处理逻辑
System.out.println("Message delivered");
}
}