导入pom
<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>
修改配置文件(使用emqtt的MySQL 认证/访问控制插件)
spring:
mqtt:
username: admin
mqpassword: admin
host-url: tcp://ip:port
client-id: zhjsbackground${random.value}
default-topic: $SYS/brokers/+/clients/#
completionTimeout: 3000
keepAlive: 60
添加读取配置类
package com.rtsm.zhjs.background.framework.emqtt.dto;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author WJH
* @date 2019/4/1110:18
*/
@ConfigurationProperties("spring.mqtt")
@Component
@Getter
@Setter
public class MqttProperties {
private String username;
private String mqpassword;
private String hostUrl;
private String clientId;
private String defaultTopic;
private String completionTimeout;
private Integer keepAlive;
}
TOPIC枚举类
package com.rtsm.zhjs.background.enums;
/**
* @author WJH
* @date 2019/4/1111:39
*/
public enum TopicName {
ROLL_CALL_DEFAULT(1,"listenDefault");
private final Integer key;
private final String value;
private TopicName(Integer key,String value){
this.key = key;
this.value = value;
}
public Integer getKey() {
return key;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return this.value;
}
}
配置类
package com.rtsm.zhjs.background.framework.emqtt;
import com.rtsm.zhjs.background.enums.TopicName;
import com.rtsm.zhjs.background.framework.emqtt.dto.MqttProperties;
import com.rtsm.zhjs.background.framework.emqtt.event.MqttEvent;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.statement.select.Top;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ApplicationObjectSupport;
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.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import javax.annotation.Resource;
import java.util.Arrays;
/**
* @author WJH
* @date 2019/4/1110:19
*/
@Configuration
@Slf4j
public class MqttConfiguration {
@Autowired
private MqttProperties mqttProperties;
@Bean
public MqttConnectOptions getMqttConnectOptions(){
MqttConnectOptions mqttConnectOptions=new MqttConnectOptions();
mqttConnectOptions.setUserName(mqttProperties.getUsername());
mqttConnectOptions.setPassword(mqttProperties.getMqpassword().toCharArray());
mqttConnectOptions.setServerURIs(new String[]{mqttProperties.getHostUrl()});
mqttConnectOptions.setKeepAliveInterval(2);
mqttConnectOptions.setKeepAliveInterval(mqttProperties.getKeepAlive());
return mqttConnectOptions;
}
@Bean
public MqttPahoClientFactory mqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setConnectionOptions(getMqttConnectOptions());
return factory;
}
@Bean
public MessageChannel mqttInputChannel() {
return new DirectChannel();
}
/**
* 配置client,监听的topic
*/
@Bean
public MessageProducer inbound() {
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter(mqttProperties.getClientId()+"_inbound", mqttClientFactory(),
mqttProperties.getDefaultTopic().split(","));
adapter.setCompletionTimeout(Long.valueOf(mqttProperties.getCompletionTimeout()));
adapter.setConverter(new DefaultPahoMessageConverter());
//默认添加TopicName中所有tipic
Arrays.stream(TopicName.values()).forEach(topicName -> adapter.addTopic(topicName.getValue(),2));
adapter.addTopic();
adapter.setQos(2);
adapter.setOutputChannel(mqttInputChannel());
return adapter;
}
/**
* 事件触发
*/
@Autowired
private ApplicationEventPublisher eventPublisher;
@Bean
@ServiceActivator(inputChannel = "mqttInputChannel")
public MessageHandler handler() {
return new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
String topic = message.getHeaders().get("mqtt_receivedTopic").toString();
String qos = message.getHeaders().get("mqtt_receivedQos").toString();
//触发事件 这里不再做业务处理,包 listener中做处理
eventPublisher.publishEvent(new MqttEvent(this,topic,message.getPayload().toString()));
log.info("topic:"+topic+" Qos:"+qos+" message:"+message.getPayload());
}
};
}
@Bean
@ServiceActivator(inputChannel = "mqttOutboundChannel")
public MessageHandler mqttOutbound() {
MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(mqttProperties.getClientId(), mqttClientFactory());
messageHandler.setAsync(true);
messageHandler.setDefaultTopic(mqttProperties.getDefaultTopic());
return messageHandler;
}
@Bean
public MessageChannel mqttOutboundChannel() {
return new DirectChannel();
}
}
设置观察者模式接收消息(事件)
package com.rtsm.zhjs.background.framework.emqtt.event;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;
/**
* topic事件
* @author WJH
* @date 2019/5/920:16
*/
@Getter
public class MqttEvent extends ApplicationEvent {
/**
*
*/
private String topic;
/**
* 发送的消息
*/
private String message;
public MqttEvent(Object source,String topic,String message) {
super(source);
this.topic = topic;
this.message = message;
}
}
EventListener设置
package com.rtsm.zhjs.background.framework.emqtt.listener;
import com.rtsm.zhjs.background.enums.TopicName;
import com.rtsm.zhjs.background.framework.emqtt.event.MqttEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
* 触发event topic 事件
* @author WJH
* @date 2019/5/920:31
*/
@Slf4j
@Component
public class JobListener {
/**
* 监听topic
* @param mqttEvent
*/
@EventListener(condition = "#mqttEvent.topic.equals(T(com.rtsm.zhjs.background.enums.TopicName).ROLL_CALL_DEFAULT.getValue())")
public void onEmqttCall(MqttEvent mqttEvent){
log.info("接收到消息:"+mqttEvent.getMessage());
}
@EventListener(condition ="@ emqttPredicate.test(#mqttEvent)")
public void onEmqttCallTest(MqttEvent mqttEvent){
log.info("测试通过:"+mqttEvent.getMessage());
}
}
package com.rtsm.zhjs.background.framework.emqtt.listener;
import com.rtsm.zhjs.background.framework.emqtt.event.MqttEvent;
import org.springframework.stereotype.Component;
/**
* @author WJH
* @date 2019/5/920:39
*/
@Component
public class EmqttPredicate {
public Boolean test(MqttEvent event){
//测试内容
return Boolean.FALSE;
}
}
emqtt消息发送
package com.rtsm.zhjs.background.framework.emqtt.service;
import com.rtsm.zhjs.background.modules.notice.entity.TzggTzxx;
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 WJH
* @date 2019/4/1110:22
*/
@Component
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface MqttServer {
void sendToMqtt( @Header(MqttHeaders.TOPIC)String topic,String data);
}