1、安装emqttd:

  Linux下用EMQ通用包安装EMQ:参考:https://www.shangmayuan.com/a/4fd1eee84fd64ca1a46c4617.html

2、添加emq的pom依赖:

     <!--emqttd 相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
        </dependency>

 3、yml文件中的配置:

# emqttd配置
  emqttd:
    # 账号
    username: admin  
    # 密码                             
    password: admin
    # emqttd的连接地址                               
    host-url: tcp://127.0.0.1:1883
    # 客户端Id(唯一)           
    client-id: xxxx
    # 默认主题                               
    default-topic: admin
    # 超时时间                          
    timeout: 30000
    # 会话心跳时间                                  
    keepalive: 100  

 4、代码部分:

  1) 配置类:

package com.eaa.common.emq.config;

import com.eaa.common.emq.MqttPushClient;
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;

import java.util.UUID;

/**
 * emq的相关配置信息
 * @create: 2021-11-17
 */
@Component
@ConfigurationProperties("spring.emqttd")
public class MqttdConfig {

    @Autowired
    private MqttPushClient mqttPushClient;

    /**
     * 用户名
     */
    private static String username;

    /**
     * 密码
     */
    private static String password;

    /**
     * 连接地址
     */
    private static String hostUrl;

    /**
     * 客户Id
     */
    private static String clientId;

    /**
     * 默认连接话题
     */
    private static String defaultTopic;

    /**
     * 超时时间
     */
    private static Integer timeout;

    /**
     * 会话心跳时间                                 
     */
    private static Integer keepalive;

    public static String getUsername() {
        return username;
    }

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

    public static String getPassword() {
        return password;
    }

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

    public static String getHostUrl() {
        return hostUrl;
    }

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

    public static String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        MqttdConfig.clientId = clientId;
    }

    public static String getDefaultTopic() {
        return defaultTopic;
    }

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

    public static Integer getTimeout() {
        return timeout;
    }

    public void setTimeout(Integer timeout) {
        MqttdConfig.timeout = timeout;
    }

    public static Integer getKeepalive() {
        return keepalive;
    }

    public void setKeepalive(Integer keepalive) {
        MqttdConfig.keepalive = keepalive;
    }

    @Bean
    public MqttPushClient getMqttPushClient() {
     // 此处的UUID.randomUUID().toString()指的就是客户端Id,若要指单个的就取上面的clientId mqttPushClient.connect(hostUrl, UUID.randomUUID().toString(), username, password, timeout, keepalive);
// 以#结尾表示订阅所有以admin开头的主题 mqttPushClient.subscribe("admin/#", 0); return mqttPushClient; } }

  2)  生产类:

package com.eaa.common.emq;

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.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * mqttd 推送客户端(生产类)
 * @create: 2021-11-17
 */
@Component
public class MqttPushClient {
    private static final Logger log = LoggerFactory.getLogger(MqttPushClient.class);

    @Autowired
    private PushCallback pushCallback;

    private  static MqttClient client;

    public static MqttClient getClient() {
        return client;
    }

    public static void setClient(MqttClient client) {
        MqttPushClient.client = client;
    }

    /**
     * 客户端连接
     * @param host           连接
     * @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.setCleanSession(true);
            options.setUserName(username);
            options.setPassword(password.toCharArray());
            options.setConnectionTimeout(timeout);
            options.setKeepAliveInterval(keepalive);
            options.setAutomaticReconnect(true);  // 自动重连
            MqttPushClient.setClient(client);
            client.setCallback(pushCallback);
            client.connect(options);
        } catch (MqttException e) {
            log.error("连接失败.......");
            e.printStackTrace();
        }
    }

    /**
     * 发布消息
     * @param qos              连接方式
     * @param retained        是否保留消息
     * @param topic           主题
     * @param pushMessage    消息体
     */
    public boolean publish(int qos, boolean retained, String topic, String pushMessage){
        MqttMessage message = new MqttMessage();
        message.setQos(qos);
        message.setRetained(retained);
        message.setPayload(pushMessage.getBytes(StandardCharsets.UTF_8));
        MqttTopic mqttTopic = MqttPushClient.getClient().getTopic(topic);
        if (null == mqttTopic){
            log.error("topic: "+ topic +"not exist!");
        }
        MqttDeliveryToken token;
        try {
            token = mqttTopic.publish(message);
            token.waitForCompletion();
       log.info("MQTT推送消息成功,message is:[{}]",message); }
catch (MqttException e) { log.error("发布失败....",e); return false; } return true; } /** * 订阅某个主题 * @param topic 主题 * @param qos 连接方式 */ public void subscribe(String topic, int qos){ // log.info("开始订阅主题:" + topic); try { MqttPushClient.getClient().subscribe(topic, qos); } catch (MqttException e) { log.error("订阅失败....", e.getMessage()); } } }

  3) 消费类:

package com.eaa.common.emq;

import com.eaa.common.emq.config.MqttdConfig;
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;

/**
 * 消费监听类(订阅之后执行)
 * @create: 2021-11-17
 */
@Component
public class PushCallback implements MqttCallback {
    private static final Logger log = LoggerFactory.getLogger(PushCallback.class);

    @Autowired
    private MqttdConfig mqttdConfig;

    private static MqttClient client;

    @Override
    public void connectionLost(Throwable throwable) {
        if (client == null || !client.isConnected()){
            //mqttdConfig.getMqttPushClient();
        }
    }

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

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        log.info("deliverComplete---" + iMqttDeliveryToken.isComplete());
    }
}

  4)测试代码:

package com.shdz.web.controller.tool;

import com.shdz.common.core.domain.AjaxResult;
import com.shdz.emqttd.MqttPushClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 测试Emqttd
 * @create: 2021-11-17
 */
@Controller
public class TestEmqttdController {

    @Autowired
    private MqttPushClient mqttPushClient;

    @PostMapping("/senMsgToMqtt")
    @ResponseBody
    public AjaxResult senMsgToMqtt(String msg){
        mqttPushClient.publish(2, true, "admin/admin", msg);
        return AjaxResult.success();
    }
}

 

5、测试:

  1)请求测试(postman):

 

 

  2)emqttd控制面板模拟

 

 

6、一些资料:

 

posted on 2022-02-23 10:33  大渔33  阅读(334)  评论(0编辑  收藏  举报