java脚手架系列13-IoT

之所以想写这一系列,是因为之前工作过程中有几次项目是从零开始搭建的,而且项目涉及的内容还不少。在这过程中,遇到了很多棘手的非业务问题,在不断实践过程中慢慢积累出一些基本的实践经验,认为这些与业务无关的基本的实践经验其实可以复刻到其它项目上,在行业内可能称为脚手架,因此决定将此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发送消息

相关推荐
阿龟在奔跑1 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list
飞滕人生TYF1 小时前
m个数 生成n个数的所有组合 详解
java·递归
代码小鑫1 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖1 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
激流丶1 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
周全全2 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
uzong2 小时前
一个 IDEA 老鸟的 DEBUG 私货之多线程调试
java·后端
AiFlutter2 小时前
Java实现简单的搜索引擎
java·搜索引擎·mybatis
飞升不如收破烂~3 小时前
Spring boot常用注解和作用
java·spring boot·后端
秦老师Q3 小时前
Java基础第九章-Java集合框架(超详细)!!!
java·开发语言