org.springframework.boot
spring-boot-starter-integration
org.springframework.integration
spring-integration-stream
org.springframework.integration
spring-integration-mqtt
redis.clients
jedis
2.9.0
#redis 配置
redis:
# Redis数据库索引(默认为0)
database: 0
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码(默认为空)
password: *****
# 连接超时时间(毫秒)
timeout: 0
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 0
package com.nari.iot.common.config;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.nari.iot.tools.JedisUtils;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.logging.Logger;
@Configuration
public class JedisConfig extends CachingConfigurerSupport {
private org.slf4j.Logger logger = LoggerFactory.getLogger(JedisConfig.class);
/**
* SpringSession 需要注意的就是redis需要2.8以上版本,然后开启事件通知,在redis配置文件里面加上
* notify-keyspace-events Ex
* Keyspace notifications功能默认是关闭的(默认地,Keyspace 时间通知功能是禁用的,因为它或多或少会使用一些CPU的资源)。
* 或是使用如下命令:
* redis-cli config set notify-keyspace-events Egx
* 如果你的Redis不是你自己维护的,比如你是使用阿里云的Redis数据库,你不能够更改它的配置,那么可以使用如下方法:在applicationContext.xml中配置
*
* @return
*/
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.pool.max-wait}")
private long maxWaitMillis;
@Bean
public JedisPool redisPoolFactory(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMinIdle(minIdle);
JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,timeout,password);
logger.info("JedisPool注入成功!");
logger.info("redis地址:" + host + ":" + port);
return jedisPool;
}
// @Bean
// public ApplicationContextProvider applicationContextProvider(){
// ApplicationContextProvider applicationContextProvider = new ApplicationContextProvider();
// applicationContextProvider.setApplicationContext();
// return applicationContextProvider;
// }
}
package com.nari.iot.tools;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 创建一个MQTT客户端
* @author wunaozai
* @date 2018-08-22
*/
public class MqttPushClient {
private static final Logger log = LoggerFactory.getLogger(MqttPushClient.class);
public static String MQTT_HOST = "";
public static String MQTT_CLIENTID = "";
public static String MQTT_USERNAME = "";
public static String MQTT_PASSWORD = "";
public static int MQTT_TIMEOUT = 10;
public static int MQTT_KEEPALIVE = 10;
private MqttClient client;
private static volatile MqttPushClient mqttClient = null;
public static MqttPushClient getInstance() {
if(mqttClient == null) {
synchronized (MqttPushClient.class) {
if(mqttClient == null) {
mqttClient = new MqttPushClient();
}
}
}
return mqttClient;
}
private MqttPushClient() {
log.info("Connect MQTT: " + this);
connect();
}
public void connect() {
try {
client = new MqttClient(MQTT_HOST, MQTT_CLIENTID, new MemoryPersistence());
MqttConnectOptions option = new MqttConnectOptions();
option.setCleanSession(true);
option.setUserName(MQTT_USERNAME);
option.setPassword(MQTT_PASSWORD.toCharArray());
option.setConnectionTimeout(MQTT_TIMEOUT);
option.setKeepAliveInterval(MQTT_KEEPALIVE);
//option.setAutomaticReconnect(true);
try {
client.setCallback(new MqttPushCallback());
client.connect(option);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发布主题,用于通知
* 默认qos为1 非持久化
* @param topic
* @param data
*/
public void publish(String topic, String data) {
publish(topic, data, 1, false);
}
/**
* 发布
* @param topic
* @param data
* @param qos
* @param retained
*/
public void publish(String topic, String data, int qos, boolean retained) {
MqttMessage message = new MqttMessage();
message.setQos(qos);
message.setRetained(retained);
message.setPayload(data.getBytes());
MqttTopic mqttTopic = client.getTopic(topic);
if(null == mqttTopic) {
log.error("Topic Not Exist");
}
MqttDeliveryToken token;
try {
token = mqttTopic.publish(message);
token.waitForCompletion();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 订阅某个主题 qos默认为1
* @param topic
*/
public void subscribe(String topic) {
subscribe(topic, 1);
}
/**
* 订阅某个主题
* @param topic
* @param qos
*/
public void subscribe(String topic, int qos) {
try {
client.subscribe(topic, qos);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.nari.iot.tools;
import com.nari.iot.bean.Info_Ai;
import com.nari.iot.bean.Message;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* MQTT 推送回调
* @author wunaozai
* @date 2018-08-22
*/
public class MqttPushCallback implements MqttCallback {
private static final Logger log = LoggerFactory.getLogger(MqttPushCallback.class);
@Override
public void connectionLost(Throwable cause) {
log.info("断开连接,建议重连" + this);
//断开连接,建议重连
MqttPushClient client = MqttPushClient.getInstance();
client.connect();
client.subscribe("cs-iot/jyysyl/data-all");
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
//log.info(token.isComplete() + "");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("接收到消息开始---------------------");
//System.out.println("Topic: " + topic);
System.out.println("Message: " + new String(message.getPayload()));
// log.info("Topic: " + topic);
//log.info("Message: " + new String(message.getPayload()));
Message messageIns = JsonUtils.toBean(new String(message.getPayload()), Message.class);
if(messageIns != null){
List infoAiList = messageIns.getInfo_ai();
if(infoAiList != null && infoAiList.size() > 0){
Set set = new HashSet();
for(int i = 0; i < infoAiList.size(); i++){
Info_Ai infoAi = infoAiList.get(i);
String key = infoAi.getKey();
if(key.indexOf("pi") != -1){
set.add(Common.CS_IOT_MESSAGE_ELEC);
}else{
set.add(Common.CS_IOT_MESSAGE_INFO);
}
}
if(set.size() > 1){
JedisUtils.set(Common.CS_IOT_MESSAGE_MIX, new String(message.getPayload()), 24*60*60);
}else if(set.contains(Common.CS_IOT_MESSAGE_ELEC)){
JedisUtils.set(Common.CS_IOT_MESSAGE_ELEC, new String(message.getPayload()), 24*60*60);
}else{
JedisUtils.set(Common.CS_IOT_MESSAGE_INFO, new String(message.getPayload()), 24*60*60);
}
}
}
System.out.println("接收到消息结束----------------------");
}
}
package com.nari.iot.service;
import com.nari.iot.tools.MqttPushClient;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class MqttService implements CommandLineRunner {
@Override
public void run(String... strings) throws Exception {
MqttPushClient.MQTT_HOST = "tcp://127.0.0.1:61613";
MqttPushClient.MQTT_CLIENTID = "subClient_my_5";
MqttPushClient.MQTT_USERNAME = "****";
MqttPushClient.MQTT_PASSWORD = "****";
MqttPushClient.MQTT_TIMEOUT = 20;
MqttPushClient.MQTT_KEEPALIVE = 10;
MqttPushClient client = MqttPushClient.getInstance();
client.subscribe("cs-iot/jyysyl/data-all");
}
}