之所以想写这一系列,是因为之前工作过程中有几次项目是从零开始搭建的,而且项目涉及的内容还不少。在这过程中,遇到了很多棘手的非业务问题,在不断实践过程中慢慢积累出一些基本的实践经验,认为这些与业务无关的基本的实践经验其实可以复刻到其它项目上,在行业内可能称为脚手架,因此决定将此java基础脚手架的搭建总结下来,分享给大家使用。
注意 :由于框架不同版本改造会有些使用的不同,因此本次系列中主要使用基本框架是 spring-boo-2.3.12.RELEASE和spring-cloud.-Hoxton.SR12,所有代码都在commonFramework项目上:https://github.com/forever1986/commonFramework/tree/master
目录
- [1 IoT](#1 IoT)
-
- [1.1 基本概念](#1.1 基本概念)
- [1.2 代码实践](#1.2 代码实践)
1 IoT
1.1 基本概念
- 物联网(IoT):指的是将无处不在(Ubiquitous)的末端设备(Devices)和设施(Facilities),包括具备"内在智能"的传感器、移动终端、工业系统、楼控系统、家庭智能设施、视频监控系统等。
- MQTT(消息队列遥测传输):是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议。
- EMQX:在MQTT协议中有两大角色:客户端(发布者/订阅者),服务端(Mqtt broker);针对客户端和服务端需要有遵循该协议的的具体实现,EMQ/EMQX就是MQTT Broker的一种实现。EMQX 基于 Erlang/OTP 平台开发的 MQTT 消息服务器,是开源社区中最流行的 MQTT 消息服务器。EMQ X 是开源百万级分布式 MQTT 消息服务器(MQTT Messaging Broker),用于支持各种接入标准 MQTT协议的设备,实现从设备端到服务器端的消息传递,以及从服务器端到设备端的设备控制消息转发。从而实现物联网设备的数据采集,和对设备的操作和控制。
1.2 代码实践
前提条件:需要有一台EMQX
参考IoT-biz子模块
1)新建IoT-biz子模块,并引入依赖
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
</dependencies>
2)创建MqttProperties、ProducerInfo、ReceiverInfo,加载配置
3)创建MqttConfiguration用于MQTT配置
java
package com.demo.iot.config;
import com.demo.iot.properties.MqttProperties;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
@EnableConfigurationProperties(MqttProperties.class)
public class MqttConfiguration {
@Autowired
private MqttProperties properties;
/**
* 创建MqttPahoClientFactory,供消费者和生产者使用
*/
@Bean
public MqttPahoClientFactory mqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
MqttConnectOptions options = new MqttConnectOptions();
options.setServerURIs(properties.getUrls());
options.setUserName(properties.getUsername());
options.setCleanSession(properties.isCleanSession());
options.setPassword(properties.getPassword().toCharArray());
factory.setConnectionOptions(options);
return factory;
}
/**
* 配置消费者
* @return
*/
@Bean
@ConditionalOnProperty(
prefix = "mqtt.receiver",
name = {"enabled"},
havingValue = "true"
)
public MessageChannel mqttInputChannel() {
return new DirectChannel();
}
@Bean
@ConditionalOnProperty(
prefix = "mqtt.receiver",
name = {"enabled"},
havingValue = "true"
)
public MessageProducer inbound() {
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter(properties.getReceiver().getClient_id(),
mqttClientFactory(), properties.getReceiver().getTopic());
adapter.setCompletionTimeout(5000);
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(properties.getReceiver().getQos());
adapter.setOutputChannel(mqttInputChannel());
return adapter;
}
@Bean
@ServiceActivator(inputChannel = "mqttInputChannel")
@ConditionalOnProperty(
prefix = "mqtt.receiver",
name = {"enabled"},
havingValue = "true"
)
public MessageHandler handler() {
return message -> {
String payload = (String) message.getPayload();
System.out.println("Received message: " + payload);
};
}
/**
* 配置生产者
* @return
*/
@Bean
@ConditionalOnProperty(
prefix = "mqtt.producer",
name = {"enabled"},
havingValue = "true"
)
public MessageChannel mqttOutboundChannel() {
return new DirectChannel();
}
@Bean
@ConditionalOnProperty(
prefix = "mqtt.producer",
name = {"enabled"},
havingValue = "true"
)
@ServiceActivator(inputChannel = "mqttOutboundChannel")
public MessageHandler mqttOutbound() {
MqttPahoMessageHandler messageHandler =
new MqttPahoMessageHandler(properties.getProducer().getClient_id(), mqttClientFactory());
messageHandler.setAsync(true);
messageHandler.setDefaultTopic(properties.getProducer().getTopic());
return messageHandler;
}
}
4)配置yaml文件
yaml
server:
port: 9983
spring:
application:
name: iot-biz-service
# 配置MQTT服务
mqtt:
urls: tcp://10.156.136.211:1883
# urls: tcp://192.168.2.201:1883
username: myeqmx
password: myeqmx
cleanSession: false
producer:
enabled: true
client_id: test_producer_1
topic: linmoo/test/data
receiver:
enabled: true
client_id: test_receiver_1
topic: linmoo/test/data
# topic: "$queue/demo/lin/data" # 共享配置
qos: 1
5)新建测试MqttController发送消息