spring boot 集成mqtt,动态数据源,时序数据库TDengine (二)

本文章使用 spring boot3、 java21、maven工程 

1、引入mqtt依赖

        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
            <version>5.5.10</version>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2、yml配置

server:
  port: 31001
  servlet:
    context-path: /dataCapture
spring:
  mqtt:
    url: tcp://192.168.1.60:1883
    username: admin
    password: public
    client:
      id: myProvider
    default:

  datasource:
    jsdb:
      driver-class-name: com.taosdata.jdbc.TSDBDriver
      url: jdbc:TAOS://192.168.1.60:6030/data_capture?charset=utf8
      username: root
      password: taosdata
    kbdb:
      driver-class-name: com.taosdata.jdbc.TSDBDriver
      url: jdbc:TAOS://192.168.1.60:6030/data_capture_kb?charset=utf8
      username: root
      password: taosdata
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 2
      max-active: 30
      min-idle: 2
      max-wait: 5000
      pool-prepared-statements: true
      validation-query: select 1
      validation-query-timeout: 1
      test-on-borrow: false
      test-on-return: true
      test-while-idle: true
      time-between-eviction-runs-millis: 10000
      min-evictable-idle-time-millis: 30001
      filters: stat


  data:
    redis:
      host: xxx.xxx.xxx.xxx
      port: 6379
      database: 0
      jedis:
        pool:
          max-active: 1000
          max-wait: -1ms
          max-idle: 10
          min-idle: 5
mybatis-plus:
  type-aliases-package: com.hiabr.web
  mapper-locations: classpath:mapper/**/*Mapper.xml
  configuration:
    default-statement-timeout: 120
    map-underscore-to-camel-case: true
    cache-enabled: false
    call-setters-on-nulls: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
  config: classpath:logback-dev.xml

3、redis配置

import com.hiabr.web.utils.ObjectRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.io.Serializable;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<Serializable, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Serializable, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        template.afterPropertiesSet();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new ObjectRedisSerializer());
        return template;
    }

}

4、mqtt核心配置 通过通配符订阅消息 /+单层匹配  /#多层匹配 参考官网 MQTT 主题与通配符(Topics & Wildcards)入门手册 | EMQ

win部署mqtt服务:Windows 本地部署 MQTT服务_windows安装mqtt-CSDN博客

docker部署mqtt服务:docker 部署 MQTT_docker mqtt-CSDN博客

        不同channel 可以通过不同的服务类通过自定义注解实现数据存储到不同数据库,多数据源参考文章:spring boot 集成mqtt,动态数据源,时序数据库TDengine (一)-CSDN博客

import com.hiabr.web.service.mqtt.JinShanMessageService;
import com.hiabr.web.service.mqtt.KaiBangMessageService;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.config.EnableIntegration;
import org.springframework.integration.endpoint.MessageProducerSupport;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;

import java.util.UUID;

/**
 * @description:
 * @author: hanwei
 * @date: 2025/5/8
 */
@Configuration
@EnableIntegration
public class MqttIntegrationConfig {

    @Value("${spring.mqtt.username}")
    private String username;

    @Value("${spring.mqtt.password}")
    private String password;

    @Value("${spring.mqtt.url}")
    private String hostUrl;

    @Autowired
    private JinShanMessageService jinShanMessageService;
    @Autowired
    private KaiBangMessageService kaiBangMessageService;

    /** ============================================================ */

    @Bean
    public MqttConnectOptions mqttConnectOptions() {
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        // mqtt服务ip:端口
        mqttConnectOptions.setServerURIs(new String[]{hostUrl});
        // Mqtt服务账号
        mqttConnectOptions.setUserName(username);
        // Mqtt服务密码
        mqttConnectOptions.setPassword(password.toCharArray());
        // 设置是否清除会话。如果设置为false,表示服务器会保留客户端的连接记录;设置为true表示每次连接到服务器都以新的身份连接‌
        mqttConnectOptions.setCleanSession(true);
        // 设置是否自动重连‌
        mqttConnectOptions.setAutomaticReconnect(true);
        // 设置连接超时时间,单位为秒‌
        mqttConnectOptions.setConnectionTimeout(100);
        // 设置心跳间隔,单位为秒‌
        mqttConnectOptions.setKeepAliveInterval(30);

        return mqttConnectOptions;
    }


    @Bean
    public MessageChannel jinShanChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel kaiBangChannel() {
        return new DirectChannel();
    }
    @Bean
    public MqttPahoClientFactory mqttPahoClientFactory(MqttConnectOptions mqttConnectOptions) {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(mqttConnectOptions);
        return factory;
    }
    // 单层匹配
    @Bean
    public MessageProducerSupport jinShanAdapter(MqttPahoClientFactory mqttPahoClientFactory) {
        String[] topics = new String[]{"SBOX/4d5b1a02d36a/+/device/data/push","SBOX/e3379cb4a610/+/device/data/push"};
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(UUID.randomUUID().toString(),
                        mqttPahoClientFactory,
                        topics);
        adapter.setOutputChannelName("jinShanChannel");
        return adapter;
    }

    // 多层级匹配 
    @Bean
    public MessageProducerSupport kaiBangAdapter(MqttPahoClientFactory mqttPahoClientFactory) {
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(UUID.randomUUID().toString(),
                        mqttPahoClientFactory,
                        "SBOX/#");
        adapter.setOutputChannelName("kaiBangChannel");
        return adapter;
    }

    
    @ServiceActivator(inputChannel = "jinShanChannel")
    public void handleJinShanData(Message<String> message) {
        jinShanMessageService.handleMessage(message);
    }

    
    @ServiceActivator(inputChannel = "kaiBangChannel")
    public void handleKaiBang(Message<String> message) {
        kaiBangMessageService.handleMessage(message);
    }
}

7、处理消息服务

import com.alibaba.fastjson.JSONObject;
import com.hiabr.web.annaotation.TargetDataSource;
import com.hiabr.web.dto.MqttMessageDTO;
import com.hiabr.web.enums.DataSourceKey;
import com.hiabr.web.service.DeviceStatusService;
import com.hiabr.web.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:
 * @author: hanwei
 * @date: 2025/5/8
 */
@Slf4j
@Service("jinShanMessageService")
public class JinShanMessageService implements MessageHandler {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private DeviceStatusService deviceStatusService;


    @Override
    public void handleMessage(Message<?> message) {
        // 处理message
        String payload = message.getPayload().toString();
        JSONObject jsonObject = JSONObject.parseObject(payload);
        String topic = message.getHeaders().get("mqtt_receivedTopic", String.class);
        log.info("主题:{}",topic);
        log.info("消息内容:{}",jsonObject.toJSONString());
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hanway116

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值