• MQTT接收字符串(1/2)


    我们现在所使用的通讯硬件大多数都是以UTF-8字符和ASCII的编码格式进行消息收发。

    MQTT测试工具,请查看上一篇内容。

    一、配置pom的maven依赖

    <dependency>
        <groupId>org.fusesource.hawtbuf</groupId>
        <artifactId>hawtbuf</artifactId>
        <version>1.11</version>
    </dependency>
    <dependency>
        <groupId>org.fusesource.hawtdispatch</groupId>
        <artifactId>hawtdispatch</artifactId>
        <version>1.22</version>
    </dependency>
    <dependency>
        <groupId>org.fusesource.hawtdispatch</groupId>
        <artifactId>hawtdispatch-transport</artifactId>
        <version>1.22</version>
    </dependency>
    <dependency>
        <groupId>org.fusesource.mqtt-client</groupId>
        <artifactId>mqtt-client</artifactId>
        <version>1.16</version>
    </dependency>

    为了代码的可阅读性,我将以下代码按照功能封装到不同的类当中。

    二、MQTT数据接收类

    package com.xxxx.controller.Server.MQTT;
    
    import com.xxxx.common.utils.PropertyUtils;
    import com.xxxx.worker.controller.Server.Execute.MessageExecute;
    import org.eclipse.paho.client.mqttv3.*;
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @title: MQTT消息订阅(接收字符串)
     * @author: hunttown
     * @date: 2021年10月17日 9:10
     * @description: 当前类用bean注入,不要使用注解注入,因为下面要将其配置到worker里
     */
    public class MQTTSubscribe implements MqttCallback {
    
        //服务器地址
        private String serverUrl = "你的服务器IP:端口";
    
        //客户端唯一标识
        private String clientid = "随便起个名字";
    
        //订阅主题
        private String subtopic = "你的订阅主题";
    
        //用户名
        private String username = "用户名";
    
        //密码
        private String password = "密码";
    
        //传输质量:0至多一次;1至少一次;2确保只有一次。
        private int qos = 0;
    
        private MqttClient client;
        private MqttConnectOptions options;
    
        private MessageExecute messageExecute = new MessageExecute();
    
        //断线重连,每10秒检测一次
        void startReconnect() {
            ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
            scheduler.scheduleAtFixedRate(new Runnable() {
                public void run() {
                    if (!client.isConnected()) {
                        try {
                            client.connect(options);
                            System.out.println("我已断线重连......");
    
                        } catch (MqttException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, 3 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
        }
    
        Boolean start() {
            try {
                client = new MqttClient(serverUrl, clientid, new MemoryPersistence());
                options = new MqttConnectOptions();
                options.setCleanSession(false);
                options.setUserName(username);
                options.setPassword(password.toCharArray());
                options.setConnectionTimeout(10);
                options.setKeepAliveInterval(20);
                options.setAutomaticReconnect(true);
                client.setCallback(this);
                client.connect(options);
                client.subscribe(subtopic, qos);
    
                System.out.println("MQTT订阅设置初始化完毕!");
                return true;
    
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("MQTT订阅设置初始化失败!");
                return false;
            }
        }
    
        public void connectionLost(Throwable cause) {
            System.out.println("------------ mqtt connection lost. ------------");
        }
    
        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {
            try {
                System.out.println("------------ delivery complete ------------" + token.isComplete());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            String msg = new String(message.getPayload());
            System.out.println("------------ 已接收到信息: ------------" + msg);
            
            //这里开始处理你的业务
            //1、如果数量较大,可使用中间件暂存信息,如:MQ
            //2、如果数量较小,可以使用异步处理
            //TODO
        }
    }

    三、线程类

    package com.xxxx.worker.controller.Server.MQTT;
    
    /**
     * @title: 启动一个线程
     * @author: hunttown
     * @date: 2020年10月17日 15:55
     * @description: 同样要使用bean注入
     */
    public class MQTTStrThread extends Thread {
    
        private static MQTTSubscribe mqttSubscribe;
    
        public void run() {
    
            //订阅任务是否启动
            boolean isStart = false;
    
            while (!isStart) {
    
                //启动,如果线程先于服务器启动,是读不到配置文件的,这里会报错,那么休眠60秒继续。
                isStart = mqttSubscribe.start();
    
                //启动成功
                if (isStart) {
                    mqttSubscribe.startReconnect();
                    System.out.println("MQTT订阅任务启动成功!");
    
                } else {
                    System.out.println("MQTT订阅任务启动失败,1分钟后继续重试!");
    
                    try {
                        Thread.sleep(60 * 1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    
        public static MQTTSubscribe getMqttSubscribe() {
            return mqttSubscribe;
        }
    
        public static void setMqttSubscribe(MQTTSubscribe mqttSubscribe) {
            MQTTStrThread.mqttSubscribe = mqttSubscribe;
        }
    }

    四、监听类

    package com.xxxx.worker.controller.TaskListener;
    
    import com.xxxx.worker.controller.Server.MQTT.MQTTStrThread;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.http.HttpServlet;
    
    /**
     * @title: MQTT消息监听类
     * @author: wangjunfu
     * @date: 2020年10月17日 18:36
     * @description: 同样是bean注入
     */
    public class MQTTStrListener extends HttpServlet implements ServletContextListener {
        public void contextInitialized(ServletContextEvent arg0) {
    
            System.out.println("----------------- MQTT:String线程已启动 --------------------------");
    
            MQTTStrThread thread = new MQTTStrThread();
            thread.setDaemon(true); //设置线程为后台线程
            thread.start();
        }
    
        public void contextDestroyed(ServletContextEvent arg0) {
            // TODO
        }
    }

    五、将监听类配置到web.xml中

    <listener>
        <!-- MQTT:接收String数据 -->
        <listener-class>com.xxxx.worker.controller.TaskListener.MQTTStrListener</listener-class>
    </listener>

    完毕! 

  • 相关阅读:
    看雪-课程-加密与解密基础
    Windows API-Wininet&WinHTTP
    OS-Windows-bat-不等待当前命令返回继续执行后续指令
    Code-OPC DA- OPC Client Code Demo
    OS-Windows-Close Windows Error Reporting
    C-长度修饰符
    Code-Linux-time_t
    Windows-bat-Path
    Code-C++-CTime&ColeDateTime
    c++命名规范、代码规范和参数设置
  • 原文地址:https://www.cnblogs.com/hunttown/p/16188849.html
Copyright © 2020-2023  润新知