1. 添加依赖
在pom.xml
中添加Eclipse Paho MQTT客户端依赖:
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>
2. 配置MQTT连接参数
在application.properties
中配置MQTT参数:
mqtt.broker=tcp://localhost:1883
mqtt.clientId=spring-boot-mqtt
mqtt.username=your-username
mqtt.password=your-password
mqtt.default-topic=test/topic
3. 创建MQTT配置类
配置MqttConnectOptions
和MqttClient
的Bean,处理连接和订阅:
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MqttConfig {
@Value("${mqtt.broker}")
private String brokerUrl;
@Value("${mqtt.clientId}")
private String clientId;
@Value("${mqtt.username}")
private String username;
@Value("${mqtt.password}")
private String password;
@Value("${mqtt.default-topic}")
private String defaultTopic;
@Bean
public MqttConnectOptions mqttConnectOptions() {
MqttConnectOptions options = new MqttConnectOptions();
options.setServerURIs(new String[]{brokerUrl});
options.setUserName(username);
options.setPassword(password.toCharArray());
options.setAutomaticReconnect(true); // 自动重连
options.setCleanSession(true);
return options;
}
@Bean
public IMqttClient mqttClient(MqttConnectOptions options) throws MqttException {
IMqttClient client = new MqttClient(brokerUrl, clientId);
client.setCallback(new MqttCallbackExtended() {
@Override
public void connectComplete(boolean reconnect, String serverURI) {
System.out.println("MQTT Connected!");
try {
// 订阅默认主题
client.subscribe(defaultTopic, 1);
} catch (MqttException e) {
e.printStackTrace();
}
}
@Override
public void connectionLost(Throwable cause) {
System.out.println("MQTT Connection Lost: " + cause.getMessage());
}
@Override
public void messageArrived(String topic, MqttMessage message) {
System.out.println("Received message: " + new String(message.getPayload()) + " on topic: " + topic);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// 消息发布完成处理
}
});
client.connect(options);
return client;
}
}
4. 创建消息发布服务
实现消息发布逻辑:
import org.eclipse.paho.client.mqttv3.IMqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MqttPublisher {
@Autowired
private IMqttClient mqttClient;
public void publish(String topic, String payload, int qos, boolean retained) throws MqttException {
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(qos);
message.setRetained(retained);
mqttClient.publish(topic, message);
}
// 重载方法,使用默认QoS和retained标志
public void publish(String topic, String payload) throws MqttException {
publish(topic, payload, 1, false);
}
}
5. 测试MQTT功能
创建REST控制器测试消息发布:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MqttController {
@Autowired
private MqttPublisher mqttPublisher;
@GetMapping("/publish")
public String publishMessage(@RequestParam String message) {
try {
mqttPublisher.publish("test/topic", message);
return "Message published: " + message;
} catch (Exception e) {
return "Error: " + e.getMessage();
}
}
}
6. 运行与测试
- 启动MQTT代理服务器(如Mosquitto):
mosquitto -c mosquitto.conf
- 运行Spring Boot应用,访问
http://localhost:8080/publish?message=HelloMQTT
发送消息。 - 使用MQTT客户端订阅主题(如MQTT.fx)订阅
test/topic
,确认接收消息。
7. 处理连接异常和自动重连
- 自动重连已在
MqttConnectOptions
中配置。 - 连接丢失处理:在
connectionLost
方法中记录日志,客户端会自动尝试重连。
8. 注意事项
- 线程安全:
IMqttClient
实例方法线程安全,可直接注入使用。 - 消息处理:在
messageArrived
中避免耗时操作,建议异步处理。 - 遗言消息:可通过
MqttConnectOptions.setWill
设置遗言主题和消息。
完整代码示例
参考上述步骤整合代码,确保配置正确,即可在Spring Boot中实现MQTT消息的发布与订阅。