1. 安装RabbitMQ并开启MQTT 协议
安装过程略,使用插件开启MQTT协议
rabbitmq-plugins enable rabbitmq_mqtt
rabbitmq-plugins enable rabbitmq_web_mqtt
2. SpringBoot项目引入依赖
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
3. MQTT连接配置类
@Configuration
public class MqttConfig {
private static String Servers[] = {"tcp://xx.xx.xx.xx:1883"};
private static String username = "xxxxx";
private static String password = "xxxxx";
@Bean
public MqttConnectOptions getMqttConnectOptions() {
MqttConnectOptions options = new MqttConnectOptions();
// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,
// 这里设置为true表示每次连接到服务器都以新的身份连接
options.setCleanSession(true);
// 设置连接的用户名
options.setUserName(username);
// 设置连接的密码
options.setPassword(password.toCharArray());
options.setServerURIs(Servers);
// 设置超时时间 单位为秒
options.setConnectionTimeout(10);
// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送心跳判断客户端是否在线,但这个方法并没有重连的机制
options.setKeepAliveInterval(20);
// 设置“遗嘱”消息的话题,若客户端与服务器之间的连接意外中断,服务器将发布客户端的“遗嘱”消息。
// options.setWill("willTopic", WILL_DATA, 2, false);
return options;
}
@Bean
public MqttPahoClientFactory mqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setConnectionOptions(getMqttConnectOptions());
return factory;
}
}
4. 生产者配置类
@Configuration
public class MqttProducerConfig {
public static final String CHANNEL_NAME_OUT = "mqttOutboundChannel";
private static String ClientId = "test/producer";
private static String Topic = "towerTest";
@Autowired
MqttPahoClientFactory mqttClientFactory;
/**
* MQTT信息通道(生产者)
*/
@Bean(name = CHANNEL_NAME_OUT)
public MessageChannel mqttOutboundChannel() {
return new DirectChannel();
}
/**
* MQTT消息处理器(生产者)
*/
@Bean
@ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
public MessageHandler mqttOutbound() {
MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(ClientId, mqttClientFactory);
messageHandler.setAsync(false);
messageHandler.setDefaultTopic(Topic);
return messageHandler;
}
}
5. 监听器配置类
@Configuration
public class MqttListener {
public static final String CHANNEL_NAME_IN = "mqttInboundChannel";
private static String ClientId = "test/consumer";
private static String ListenTopic = "towerTest";
@Autowired
MqttPahoClientFactory mqttClientFactory;
/**
* MQTT消息通道(消费者)
*/
@Bean(name = CHANNEL_NAME_IN)
public MessageChannel mqttInboundChannel() {
return new DirectChannel();
}
/**
* MQTT消息订阅绑定(消费者)
*/
@Bean
public MessageProducer inbound() {
MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(ClientId, mqttClientFactory, ListenTopic);
adapter.setCompletionTimeout(5000);
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(1);
adapter.setOutputChannel(mqttInboundChannel());
return adapter;
}
/**
* MQTT消息监听器(消费者)
* MessageHandler: org.springframework:spring-messaging
*/
@Bean
@ServiceActivator(inputChannel = CHANNEL_NAME_IN)
public MessageHandler handlerTest() {
return message -> {
try {
String string = message.getPayload().toString();
System.out.println("接收到消息:" + string);
} catch (MessagingException e) {
e.printStackTrace();
//logger.info(e.getMessage());
}
};
}
}
6. 消息发送器
@Component
@MessagingGateway(defaultRequestChannel = MqttProducerConfig.CHANNEL_NAME_OUT)
public interface MqttSender {
/**
* 发送信息到MQTT服务器
*
* @param data 发送的文本
*/
void sendToMqtt(String data);
/**
* 发送信息到MQTT服务器
*
* @param topic 主题
* @param payload 消息主体
*/
void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);
/**
* 发送信息到MQTT服务器
*
* qos:
* 0 至多一次,数据可能丢失
* 1 至少一次,数据可能重复
* 2 只有一次,且仅有一次,最耗性能
*
* @param topic 主题
* @param qos 服务质量
* @param payload 消息主体
*/
void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
}
7. MqttController
@RestController
public class MqttController {
@Resource
private MqttSender iMqttSender;
/**
* 发送MQTT消息
*
* @param message 消息内容
* @return 返回
*/
@PostMapping(value = "/mqtt", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> sendMqtt(@RequestParam(value = "msg") String message) {
System.out.println("================生产MQTT消息================" + message);
iMqttSender.sendToMqtt(message);
return new ResponseEntity<>("OK", HttpStatus.OK);
}
/**
* 发送MQTT消息
*
* @param message 消息内容
* @return 返回
*/
@PostMapping(value = "/mqtt2", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> sendMqtt2(@RequestParam(value = "msg") String message) {
System.out.println("================生产MQTT消息================" + message);
iMqttSender.sendToMqtt("hello", message);
return new ResponseEntity<>("OK", HttpStatus.OK);
}
}