mqtt服务安装
https://blog.csdn.net/ko0491/article/details/103529897
本文代码 https://github.com/ln0491/mqtt
新建项目mqtt
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ghgcn</groupId>
<artifactId>mqtt</artifactId>
<version>1.0.0</version>
<name>mqtt</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
资源文件
com.mqtt.urls=tcp://192.168.230.128:1883
com.mqtt.clientId=test-inbound
com.mqtt.topics=topic1,topic2
com.mqtt.username=test
com.mqtt.password=test2019
属性类
package com.ghgcn.mqtt.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author 刘楠
* @version 1.0.0
* @date 2019/12/13 15:31
*/
@Data
@Configuration
@ConfigurationProperties("com.mqtt")
public class MqttProperties {
private String urls;
private String username;
private String password;
private String clientId;
private String topics;
}
配置类2个
package com.ghgcn.mqtt.config;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
/**
* @author 刘楠
* @version 1.0.0
* @date 2019/12/13 15:39
*/
@Configuration
@Slf4j
public class MqttInboundConfiguration {
@Autowired
private MqttProperties mqttProperties;
@Bean
public MessageChannel mqttInputChannel() {
return new DirectChannel();
}
@Bean
public MqttConnectOptions getMqttConnectOptions(){
MqttConnectOptions mqttConnectOptions=new MqttConnectOptions();
mqttConnectOptions.setServerURIs( mqttProperties.getUrls().split(","));
mqttConnectOptions.setKeepAliveInterval(100);
mqttConnectOptions.setMaxInflight(1000);
mqttConnectOptions.setUserName(mqttProperties.getUsername());
mqttConnectOptions.setPassword(mqttProperties.getPassword().toCharArray());
mqttConnectOptions.setAutomaticReconnect(true);
return mqttConnectOptions;
}
@Bean
public MqttPahoClientFactory mqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setConnectionOptions(getMqttConnectOptions());
return factory;
}
@Bean
public MessageProducer inbound(MqttPahoClientFactory mqttPahoClientFactory) {
String[] inboundTopics = mqttProperties.getTopics().split(",");
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter(mqttProperties.getClientId(),
mqttPahoClientFactory,inboundTopics);
adapter.setCompletionTimeout(5000);
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(1);
adapter.setOutputChannel(mqttInputChannel());
return adapter;
}
@Bean
@ServiceActivator(inputChannel = "mqttInputChannel")
public MessageHandler handler() {
return message -> log.info("收到消息:"+ message.getPayload());
}
}
package com.ghgcn.mqtt.config;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
/**
* @author 刘楠
* @version 1.0.0
* @date 2019/12/13 15:36
*/
@Configuration
public class MqttOutboundConfiguration {
@Autowired
private MqttProperties mqttProperties;
@Autowired
private MqttPahoClientFactory mqttPahoClientFactory;
@Bean
@ServiceActivator(inputChannel = "mqttOutboundChannel")
public MessageHandler mqttOutbound() {
MqttPahoMessageHandler messageHandler =
new MqttPahoMessageHandler(mqttProperties.getClientId(), mqttPahoClientFactory);
messageHandler.setAsync(true);
messageHandler.setDefaultTopic(mqttProperties.getTopics());
return messageHandler;
}
@Bean
public MessageChannel mqttOutboundChannel() {
return new DirectChannel();
}
}
发送消息接口与Controller
package com.ghgcn.mqtt.service;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
/**
* @author 刘楠
* @version 1.0.0
* @date 2019/12/13 15:40
*/
@Component
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface MqttGateway {
/**
* 发送信息
* @param data
*/
void sendToMqtt(String data);
/**
* 指定主题发送信息
* @param topic
* @param payload
*/
void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);
/**
* 指定主题和qos发送信息
* @param topic
* @param qos
* @param payload
*/
void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
}
- controller
package com.ghgcn.mqtt.controller;
import com.ghgcn.mqtt.service.MqttGateway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 刘楠
* @version 1.0.0
* @date 2019/12/13 10:31
*/
@RestController
public class TestController {
@Autowired
private MqttGateway mqttGateway;
@RequestMapping("/sendMqtt")
public String sendMqtt(String topic,String sendData){
mqttGateway.sendToMqtt(topic,sendData);
return "OK";
}
}
启动类
@SpringBootApplication
@EnableConfigurationProperties(MqttProperties.class)
public class MqttApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(MqttApplication.class)
// .web(WebApplicationType.NONE)
.run(args);
}
}
启动后
使用使用MQTT.fx进行连接。
推送消息
java端收到消息
python 发送消息
# !/usr/bin/python
# -*-coding:utf-8-*-
# @Author: 刘楠
# @Time: 2019/12/12 17:01
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe("lettuce")
def on_message(client, userdata, msg):
print(client,userdata,msg.topic + " " + str(msg.payload))
client = mqtt.Client()
client.username_pw_set("test", "test2019") # 必须设置,否则会返回「Connected with result code 4」
client.on_connect = on_connect
client.on_message = on_message
HOST = "192.168.230.128"
client.connect(HOST, 1883, 60)
# 向topic1发送100条消息
for i in range(100):
client.publish(topic="topic1",payload="去放醋范德萨范德萨 %s"%i)
client.loop_forever()
重要
setClearsession设置为false,再次重连接时,还是原来的session,就可以收到离线消息
发送消息时retain设置为false,不然重新连接时,最后一条消息会收到2条