SpringBoot+MQTT协议+Maven

18 篇文章 2 订阅
14 篇文章 0 订阅

SpringBoot+MQTT协议+Maven


前言

MQTT(Message Queuing Telemetry Transport)是基于二进制消息的发布/订阅编程模式的消息协议,非常适合需要低功耗和网络带宽有限的IoT场景。这里整理关于mqtt在springboot中集成使用。


提示:以下是本篇文章正文内容,下面案例可供参考

一、maven依赖

        <dependency>
            <groupId>org.eclipse.paho</groupId>
            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
            <version>1.2.2</version>
        </dependency>

二、自定义Springboot的yml配置文件以及相关配置类

1.配置YML

代码如下(示例):

server:
  tomcat:
    uri-encoding: UTF-8
    max-threads: 1000
    min-spare-threads: 30
  port: 8080
  connection-timeout: 5000

#mqtt服务
mqtt:
  host: "tcp://xxxx:1883" #MQTT服务地址和断开
  serverClientId: "iot"
  user: "admin"
  pwd: "admin"

三、MQTT工具类

1.MQTT工具类Java代码

/**
 * MQTT工具类
 *
 * @author SongWei
 */
@Service
@Slf4j
public class MqttUtils {
    @Value("${mqtt.host}")
    private String host;
    @Value("${mqtt.serverClientId}")
    private String serverClientId;
    @Value("${mqtt.user}")
    private String user;
    @Value("${mqtt.pwd}")
    private String pwd;

    /**
     * 订阅主题
     */
    public boolean subscribe(String theme) {
        try {
            if (StrUtil.isEmpty(theme)) {
                theme = TopicEnum.DEFAULT.getName();
            }
            //MQTT的连接设置
            MqttClient client = new MqttClient(host, serverClientId, new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setCleanSession(Constants.CLEAN_SESSION);
            options.setUserName(user);
            options.setPassword(pwd.toCharArray());
            options.setConnectionTimeout(Constants.CONNECTION_TIMEOUT);
            options.setKeepAliveInterval(Constants.KEEP_ALIVE_INTERVAL);
            //设置断开后重新连接
            options.setAutomaticReconnect(true);
            //设置回调
            client.setCallback(new PushCallback());
            MqttTopic topic = client.getTopic(theme);
            //如项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
            options.setWill(topic, Constants.WILL_PAYLOAD, Constants.QOS, true);
            client.connect(options);
            int[] qos = {Constants.QOS};
            String[] topic1 = {theme};
            client.subscribe(topic1, qos);
            return true;
        } catch (Exception e) {
            log.error("推送消息--异常\nclientId:{}\nexception:{}", serverClientId, e.toString());
            return false;
        }
    }

    /**
     * 推送消息
     */
    public boolean pushMsg(String clientId, String theme, String msg) {
        if (StrUtil.isEmpty(theme)) {
            theme = TopicEnum.DEFAULT.getName();
        }
        MqttTopic connect = this.getTopic(clientId, theme);
        MqttMessage message = new MqttMessage();
        //保证消息能到达一次
        message.setQos(1);
        message.setRetained(true);
        //String str = "{\"msg\":\"" + msg + "\"}";
        message.setPayload(msg.getBytes());
        try {
            this.publish(connect, message);
            return true;
        } catch (Exception e) {
            log.error("推送消息--异常\nclientId:{}\nexception:{}", clientId, e.toString());
            return false;
        }
    }

    /**
     * 获取订阅
     */
    private MqttTopic getTopic(String clientId, String theme) {
        MqttClient mqttClient = this.mqttClient(clientId);
        MqttConnectOptions options = new MqttConnectOptions();
        options.setCleanSession(false);
        options.setUserName(user);
        options.setPassword(pwd.toCharArray());
        // 设置超时时间
        options.setConnectionTimeout(10);
        // 设置会话心跳时间
        options.setKeepAliveInterval(20);
        try {
            mqttClient.setCallback(new PushCallback());
            mqttClient.connect(options);
            return mqttClient.getTopic(theme);
        } catch (Exception e) {
            log.error("获取订阅--异常\nclientId:{}\ntheme:{}\nexception:{}", clientId, theme, e.toString());
        }
        return null;
    }

    /**
     * 连接mqtt服务
     */
    private MqttClient mqttClient(String clientId) {
        MqttClient mqttClient = null;
        try {
            mqttClient = new MqttClient(host, clientId, new MemoryPersistence());
        } catch (MqttException e) {
            log.error("连接MQTT服务器--异常\nclientId:{}\nexception:{}", clientId, e.toString());
        }
        return mqttClient;
    }

    /**
     * 推送消息
     */
    private void publish(MqttTopic mqttTopic, MqttMessage message) throws Exception {
        if (ObjectUtil.isNotNull(mqttTopic)) {
            MqttDeliveryToken token = mqttTopic.publish(message);
            token.waitForCompletion();
            if (!token.isComplete()) {
                log.error("推送消息--失败--msg:{}", JSON.toJSONString(message));
            }
        } else {
            log.error("推送消息--失败--msg:{}", JSON.toJSONString(message));
        }
    }
}

四、发布消息的回调类

1.发布消息的回调类Java代码

/**
 * 发布消息的回调类
 * <p>
 * 必须实现MqttCallback的接口并实现对应的相关接口方法CallBack 类将实现 MqttCallBack。
 * 每个客户机标识都需要一个回调实例。在此示例中,构造函数传递客户机标识以另存为实例数据。
 * 在回调中,将它用来标识已经启动了该回调的哪个实例。
 * 必须在回调类中实现三个方法:
 * public void messageArrived(MqttTopic topic, MqttMessage message)接收已经预订的发布。
 * public void connectionLost(Throwable cause)在断开连接时调用。
 * public void deliveryComplete(MqttDeliveryToken token))
 * 接收到已经发布的 QoS 1 或 QoS 2 消息的传递令牌时调用。
 * 由 MqttClient.connect 激活此回调。
 * </p>
 */
@Slf4j
public class PushCallback implements MqttCallback {
    @Override
    public void connectionLost(Throwable cause) {
        //连接丢失后,一般在这里面进行重连
        log.info("PushCallback--连接断开" + JSON.toJSONString(cause));
    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        if (!token.isComplete()) {
            log.info("PushCallback--deliveryComplete--异常:" + JSON.toJSONString(token));
        }
    }

    @Override
    public void messageArrived(String theme, MqttMessage message) {
        try {
            log.info("【订阅回调】\ttheme:{}\tqos:{}\npayload:{}", theme, message.getQos(), new String(message.getPayload()));
        } catch (Exception e) {
            log.error("【订阅回调】--异常\ttheme:{}\nmessage:{}", theme, JSON.toJSONString(message));
        }
    }
}

五、测试消息发布和消息接收

1.消息发布和消息接收Java代码

@RestController
@RequestMapping("/test")
public class Test {
    @Autowired
    private MqttUtils mqttUtils;

    /**
     * 推送消息
     *
     * @param theme 主题
     * @param msg   发送消息
     * @return Object <p></p>
     * @author SongWei
     * @date 2021/5/6 15:08
     * @since 1.0.0
     */
    @GetMapping("/pushMsg")
    public Object pushMsg(@RequestParam(value = "theme", required = false) String theme, @RequestParam(value = "msg") String msg) {
        return ResultUtil.isOk(mqttUtils.pushMsg(String.valueOf(System.currentTimeMillis()), theme, msg));
    }

    /**
     * 订阅主题
     *
     * @param theme 主题
     * @return Object <p></p>
     * @author SongWei
     * @date 2021/5/6 15:08
     * @since 1.0.0
     */
    @GetMapping("/subscribe")
    public Object subscribe(@RequestParam(value = "theme", required = false) String theme) {
        return ResultUtil.isOk(mqttUtils.subscribe(theme));
    }
}

总结

以上是MQTT消息发布和接收的核心代码,还有一步最关键的是部署MQTT服务器

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值