• 用emqx做mqtt客户端


    最近项目中有一个需求,要用mqtt协议接收路侧设备的数据到云平台上,所以,研究了一下mqtt客户端的制作方法。

    mqtt协议是一个发布订阅模式的协议。

    这篇文章主要记录下我搭建mqttbroker和写mqtt客户端的过程,是记录,不是教程,无意教程。

    一、下载安装emqx

    emqx是一个mqtt的broker软件,这个软件是比较好用的一个broker软件,以前用过mosquitto软件做mqtt的broker,但是mosquitto没有emqx易用,所以就放弃了。

    从emqx的官网上下载得到emqx-4.4.1-otp24.1.5-3-el7-amd64.zip,unzip解压出来一个emqx的文件夹。

    进入到emqx/bin下执行 emqx start,就将emqx启动起来了。

    [root@localhost bin]# ./emqx start
    WARNING: There seem to be missing dynamic libs from the OS. Using libs from /root/emqx/dynlibs
    EMQ X Broker 4.4.1 is started successfully!
    [root@localhost bin]#
    

    查看emqx的运行状态用bin下的emqx_ctl命令。

    [root@localhost bin]# ./emqx_ctl status
    Node 'emqx@127.0.0.1' 4.4.1 is started
    [root@localhost bin]# 
    

    经过以上的下载、解压、启动、查看状态四个步骤,就将emqx软件正常运行起来了。

    二、mqtt客户端的编写

    编写mqtt客户端,是需要eclips的paho库的,这个库是一个mqtt客户端的编程接口库。

    在基于maven的java项目中,要增加一个dependency。

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

    接下来就是写client的代码了。

    下面的代码中有发送消息的代码,也有接收消息的代码,接收消息的代码就是那个OnMessageCallback,有了这个Callback类就可以接收mqtt消息了。

    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    
    import java.nio.charset.StandardCharsets;
    
    
    public class App {
        public static void main(String[] args) {
            String subTopic = "testtopic/#";
            String pubTopic = "testtopic/1";
            String content = "哈哈哈,我又来了。";
            int qos = 2;
            String broker = "tcp://123.56.182.37:1883"; //这里是broker的地址
            String clientId = "emqx_test";
            MemoryPersistence persistence = new MemoryPersistence();
    
            try {
                MqttClient client = new MqttClient(broker, clientId, persistence);
    
                // MQTT 连接选项
                MqttConnectOptions connOpts = new MqttConnectOptions();
                connOpts.setUserName("emqx_test");
                connOpts.setPassword("emqx_test_password".toCharArray());
                // 保留会话
                connOpts.setCleanSession(true);
    
                // 设置回调,这个回调类是用来接收mqtt消息的,如果只是想要发布mqtt消息,那么就不需要这个回调了。
                // 当然,如果只是想接收mqtt消息,不想发送,那么就只设置这个回调,下面的发送代码也就不需要了
                client.setCallback(new OnMessageCallback());
    
                // 建立连接
                System.out.println("Connecting to broker: " + broker);
                client.connect(connOpts);
    
                System.out.println("Connected");
                System.out.println("Publishing message: " + content);
    
                // 订阅
                client.subscribe(subTopic);
    
                // 消息发布所需参数
                long i = 0;
                while (i < 10e10) {
                    MqttMessage message = new MqttMessage(content.getBytes(StandardCharsets.UTF_8));
                    message.setQos(qos);
                    client.publish(pubTopic, message);
    
                    Thread.sleep(10000);
                    i++;
    
                    System.out.println("Message published, i = " + i);
                }
    
                client.disconnect();
                System.out.println("Disconnected");
                client.close();
                System.exit(0);
            } catch (MqttException me) {
                System.out.println("reason " + me.getReasonCode());
                System.out.println("msg " + me.getMessage());
                System.out.println("loc " + me.getLocalizedMessage());
                System.out.println("cause " + me.getCause());
                System.out.println("excep " + me);
                me.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
    import org.eclipse.paho.client.mqttv3.MqttCallback;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
    
    public class OnMessageCallback implements MqttCallback {
        public void connectionLost(Throwable cause) {
            // 连接丢失后,一般在这里面进行重连
            System.out.println("连接断开,可以做重连");
        }
    
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            // subscribe后得到的消息会执行到这里面
            System.out.println("接收消息主题:" + topic);
            System.out.println("接收消息Qos:" + message.getQos());
    
            System.out.println("接收消息内容:" + new String(message.getPayload(), "utf-8"));
        }
    
        public void deliveryComplete(IMqttDeliveryToken token) {
            System.out.println("deliveryComplete---------" + token.isComplete());
        }
    }
    

    以上两步就可以完成一个具备基本功能的mqtt协议客户端了,这个客户端既可以发布消息,也可以接收消息。当然,如果只想要一个方面的功能,也可以适当裁剪以适应自己的需要。

    参考资料:
    1、https://www.emqx.io/docs/zh/v4.4/getting-started/install.html

  • 相关阅读:
    [LeetCode] 71. Simplify Path 简化路径
    [LeetCode] 173. Binary Search Tree Iterator 二叉搜索树迭代器
    [LeetCode] 142. Linked List Cycle II 链表中的环 II
    [LeetCode] 141. Linked List Cycle 链表中的环
    读经典——《CLR via C#》(Jeffrey Richter著) 笔记_友元程序集
    读经典——《CLR via C#》(Jeffrey Richter著) 笔记_通过ILDasm.exe查看编译器如何将类型及其成员编译成元数据
    tfs强行签入和删除工作区
    需要提升权限才能运行dism
    读经典——《CLR via C#》(Jeffrey Richter著) 笔记_类型的各种成员
    Jquery 获取URL中的参数
  • 原文地址:https://www.cnblogs.com/zhangzl419/p/16070411.html
Copyright © 2020-2023  润新知