ruoyi整合mqtt

发布时间 2023-04-21 19:31:19作者: binbinx

https://www.cnblogs.com/SjhCode/p/mqtt.html

ruoyi整合mqtt

mqtt
报错客户机未连接32104,可能是没连接上,也可能是两个客户端clientID相同,也可能是同一台机子subscribe(Topic,Qos)订阅了多次
在消费时,需要对方的通道有发送测试信息,我们才能取出来消费,消费完出队。

 

本地测试:

https://mqttx.app/zh

下载MQTTX测试工具,创建新连接,创建订阅。

将配置文件中的信息对应填写,编写java代码启动项目;

在MQTTX中的发送窗口中,选好对应topic,写入json发送。

看到控制台有log输出则成功;

 

导入依赖

 
        <!-- mqtt -->
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
        </dependency>
 

 配置

 
  mqtt:
    username: admin
    password: admin
    host-url: tcp://broker.emqx.io:1883   # 服务器的地址和端口,这个需要改
    clientID: test1000    # 这个改不改随意,但不同的客户端肯定不能一样
    default-topic: testtopic/1       # 默认主题
    timeout: 100
    keepalive: 100
 
 
package com.ruoyi.web.controller.Mqtt;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @Classname MqttConfig
 * @Description mqtt相关配置信息
 * @Date 2020/3/5 11:00
 * @Created by bam
 */
@Component
@ConfigurationProperties("spring.mqtt")
public class MqttConfig {
    @Autowired
    private MqttPushClient mqttPushClient;

    /**
     * 用户名
     */
    // @Value("username")
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 连接地址
     */
    private String hostUrl;
    /**
     * 客户Id
     */
    private String clientID;
    /**
     * 默认连接话题
     */
    private String defaultTopic;
    /**
     * 超时时间
     */
    private int timeout;
    /**
     * 保持连接数
     */
    private int keepalive;

    @Bean
    public MqttPushClient getMqttPushClient() {
//        System.out.println("hostUrl: "+ hostUrl);
//        System.out.println("clientID: "+ clientID);
//        System.out.println("username: "+ username);
//        System.out.println("password: "+ password);
//        System.out.println("timeout: "+timeout);
//        System.out.println("keepalive: "+ keepalive);
        mqttPushClient.connect(hostUrl, clientID, username, password, timeout, keepalive);
        System.out.println("MQTT服务启动成功");
        // 以/#结尾表示订阅所有以test开头的主题
        mqttPushClient.subscribe(defaultTopic, 0);
        return mqttPushClient;
    }


    public void setMqttPushClient(MqttPushClient mqttPushClient) {
        this.mqttPushClient = mqttPushClient;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getHostUrl() {
        return hostUrl;
    }

    public void setHostUrl(String hostUrl) {
        this.hostUrl = hostUrl;
    }

    public String getClientID() {
        return clientID;
    }

    public void setClientID(String clientID) {
        this.clientID = clientID;
    }

    public String getDefaultTopic() {
        return defaultTopic;
    }

    public void setDefaultTopic(String defaultTopic) {
        this.defaultTopic = defaultTopic;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public int getKeepalive() {
        return keepalive;
    }

    public void setKeepalive(int keepalive) {
        this.keepalive = keepalive;
    }
}
 

 

 
package com.ruoyi.web.controller.Mqtt;

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.ruoyi.web.controller.Mqtt.MqttPushClient;

/** * * @author bam * 2020年3月5日 * MqttPushClient.java * */ @Component public class MqttPushClient { private static final Logger logger = LoggerFactory.getLogger(com.ruoyi.web.controller.Mqtt.MqttPushClient.class); @Autowired private com.ruoyi.web.controller.Mqtt.PushCallback pushCallback; @Value("${spring.mqtt.default-topic}") private String topic ; private static MqttClient client; private static MqttClient getClient() { return client; } private static void setClient(MqttClient client) { com.ruoyi.web.controller.Mqtt.MqttPushClient.client = client; } /** * 客户端连接 * * @param host ip+端口 * @param clientID 客户端Id * @param username 用户名 * @param password 密码 * @param timeout 超时时间 * @param keepalive 保留数 */ public void connect(String host, String clientID, String username, String password, int timeout, int keepalive) { MqttClient client; try { client = new MqttClient(host, clientID, new MemoryPersistence()); MqttConnectOptions options = new MqttConnectOptions(); options.setAutomaticReconnect(true); options.setCleanSession(true); options.setUserName(username); options.setPassword(password.toCharArray()); options.setConnectionTimeout(timeout); options.setKeepAliveInterval(keepalive); com.ruoyi.web.controller.Mqtt.MqttPushClient.setClient(client); subscribe(topic,2); try { client.setCallback(pushCallback); client.connect(options); } catch (Exception e) { try { client.reconnect(); }catch (Exception e1){ e1.printStackTrace(); } e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } } /** * 发布 * * @param qos 连接方式 * @param retained 是否保留 * @param topic 主题 * @param pushMessage 消息体 */ public void publish(int qos, boolean retained, String topic, String pushMessage) { MqttMessage message = new MqttMessage(); message.setQos(qos); message.setRetained(retained); message.setPayload(pushMessage.getBytes()); MqttTopic mTopic = MqttPushClient.getClient().getTopic(topic); if (null == mTopic) { logger.error("topic not exist"); } MqttDeliveryToken token; try { logger.info(mTopic.toString()); token = mTopic.publish(message); token.waitForCompletion(); } catch (MqttPersistenceException e) { e.printStackTrace(); } catch (MqttException e) { e.printStackTrace(); } } /** * 订阅某个主题 * * @param topic 主题 * @param qos 连接方式 */ public void subscribe(String topic, int qos) { logger.info("开始订阅主题" + topic); try { MqttPushClient.getClient().subscribe(topic, qos); } catch (MqttException e) { e.printStackTrace(); } } }
 

 

package com.ruoyi.web.controller.Mqtt;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.web.controller.Mqtt.MqttPushClient;
import com.ruoyi.web.controller.Mqtt.MqttConfig;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.websocket.*;

import javax.annotation.Resource;
import java.lang.reflect.Method;


/**
 * @Classname PushCallback
 * @Description 消费监听类
 * @Date 2019/4/11 23:31
 * @Created by Jack
 */
@Component
public class PushCallback implements MqttCallback {
    private static final Logger logger = LoggerFactory.getLogger(MqttPushClient.class);

    @Autowired
    private MqttConfig mqttConfig;

    private static MqttClient client;

    @Resource
    private WebSocket webSocket;

    @Override
    public void connectionLost(Throwable throwable) {
        // 连接丢失后,一般在这里面进行重连
        logger.info("连接断开,可以做重连");
        if (null != client) {
            mqttConfig.getMqttPushClient();
        }
    }

    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        // subscribe后得到的消息会执行到这里面
        logger.info("接收消息主题 : " + topic);
        logger.info("接收消息Qos : " + mqttMessage.getQos());
        logger.info("接收消息内容 : " + new String(mqttMessage.getPayload()));

        String msg= new String(mqttMessage.getPayload());
        String data = JSONObject.parseObject(msg).getString("data");
//        webSocket.sendMessage(data);

    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        logger.info("消息发送成功---------" + iMqttDeliveryToken.isComplete());
    }
}