SpringBoot MQTT使用及Centos8下emqx4.4版本的安装

服务器下载emqx

下载文档地址
使用文档地址

1. Package安装

历史版本

  1. 下载包
wget https://www.emqx.com/zh/downloads/broker/4.4.6/emqx-4.4.6-otp24.1.5-3-el8-amd64.rpm
  1. 安装 EMQX
sudo yum install -y emqx-4.4.6-otp24.1.5-3-el8-amd64.rpm
  1. 启动 EMQX
sudo emqx start
sudo systemctl start emqx
  1. 开机自启动
sudo systemctl enable emqx
# 重新加载某个服务的配置文件
sudo systemctl daemon-reload

2. 后台地址

http://服务器IP:18083/

初始账号:admin
初始密码:public

导入包

可以去阿里云仓库查看最新的包

    compile 'org.springframework.boot:spring-boot-starter-integration'
    compile 'org.springframework.integration:spring-integration-stream'
    compile 'org.springframework.integration:spring-integration-mqtt:5.5.9' 

application.yml配置

username和password这个用户名和密码是需要在服务器上配置

# /etc/emqx/plugins/emqx_auth_mnesia.conf
# 中间的1代表第一组
auth.user.1.username = admin
auth.user.1.password = public
mqtt:
  username: admin
  password: public 
  host-url:
    - tcp://服务器IP:1883 # 不同的方式对应不同的端口 tcp对应的是1883
  client-id: test # 客户端id,最好唯一
  default-topic: /testtopic # 默认监听端口 可以用规则匹配 例如 /testtopic/# 可以监听到 以/testtopic/为前缀的所有端口 举例 /testtopic/1/testtopic/test/1等等
  completionTimeout: 3000

代码

1. 配置文件:MqttProperties

@Data
@Component
@ConfigurationProperties("mqtt")
public class MqttProperties {
    private String username;
    private String password;
    private String[] hostUrl;
    private String clientId;
    private String defaultTopic;
    private int completionTimeout;
}

2. 监听文件:MqttConfig

包含消息接收和发送

@Configuration
@IntegrationComponentScan
public class MqttConfig {

    @Autowired
    MqttProperties mqttProperties;

    @Autowired
    MqttGateway mqttGateway;

    private MqttPahoMessageDrivenChannelAdapter adapter;


    /**
     * 添加topic
     *
     * @param topic
     */
    public void addTopic(String topic) {
        adapter.addTopic(topic);
    }

    /**
     * 删除topic
     *
     * @param topic
     */
    public void removeTopic(String topic) {
        adapter.removeTopic(topic);
    }

    @Bean
    public MqttConnectOptions getMqttConnectOptions() {
        // MQTT的连接设置
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        // 设置连接的用户名
        mqttConnectOptions.setUserName(mqttProperties.getUsername());
        // 设置连接的密码
        mqttConnectOptions.setPassword(mqttProperties.getPassword().toCharArray());
        // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,
        // 把配置里的 cleanSession 设为false,客户端掉线后 服务器端不会清除session,
        // 当重连后可以接收之前订阅主题的消息。当客户端上线后会接受到它离线的这段时间的消息
        mqttConnectOptions.setCleanSession(true);
        // 设置发布端地址
        mqttConnectOptions.setServerURIs(mqttProperties.getHostUrl());
        // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
        mqttConnectOptions.setKeepAliveInterval(20);
        mqttConnectOptions.setAutomaticReconnect(true);
        return mqttConnectOptions;
    }

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(getMqttConnectOptions());
        return factory;
    }

    /**
     * 接收通道
     *
     * @return
     */
    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }

    /**
     * 配置client,监听的topic
     *
     * @return
     */
    @Bean
    public MessageProducer inbound() {
        adapter = new MqttPahoMessageDrivenChannelAdapter(mqttProperties.getClientId() + "_inbound", mqttClientFactory(), mqttProperties.getDefaultTopic());
        adapter.setCompletionTimeout(mqttProperties.getCompletionTimeout());
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
        adapter.setOutputChannel(mqttInputChannel());
        return adapter;
    }

    /**
     * 通过通道获取数据
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")
    @Transactional(rollbackFor = Exception.class)
    public MessageHandler handler() {
        return message -> {
            String topic = Objects.requireNonNull(message.getHeaders().get("mqtt_receivedTopic")).toString();
            /**
             * 根据监听到的topic规则去处理/存储数据
             * 接收到的数据是字符串,最好先转成实体类或Map再处理
             */
        };
    }
    
    /**
     * 通过通道发送数据
     */
    @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();
    }
}

3. 发送消息中间件:MqttGateway

@Component
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface MqttGateway {
    void sendToMqtt(String data, @Header(MqttHeaders.TOPIC) String topic);
}

4. 测试:MqttController

@RestController
public class MqttController {

    @Autowired
    private MqttGateway mqttGateway;

    @Resource
    private MqttConfig mqttConfig;
    
    /**
     * 发送消息
     */
    @PostMapping("/send-message")
    public String sendMessage(@ApiParam(value = "发送的内容", required = true) @RequestParam String payload, @ApiParam(value = "发送的主题", required = true) @RequestParam String topic) {
        mqttGateway.sendToMqtt(payload, topic);
        return "发送成功";
    }
    
    /**
     * 订阅主题
     */
    @PostMapping("/add-topic")
    public String addTopic(@ApiParam(value = "要订阅的主题", required = true) @RequestParam String topic) throws MqttException {
        mqttConfig.addTopic(topic);
        return "订阅成功";
    }
    
    /**
     * 取消订阅topic
     */
    @PostMapping("/remove-topic")
    public String removeTopic(@ApiParam(value = "要取消订阅的主题", required = true) @RequestParam String topic) throws MqttException {
        mqttConfig.removeTopic(topic);
        return "取消订阅成功";
    }
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值