Java连接MQTT 订阅和发布

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010277446/article/details/86470377

MQTT的集成和使用

基于MQTT协议在物联网系统中数据交互的重要角色,入门java项目中mqtt初始化连接与订阅、发布
MQTT服务端broker搭建可移步小生博文:

一、Maven引入MQTT包

此演示选用mqtt库:org.eclipse.paho

<!-- https://mvnrepository.com/artifact/org.eclipse.paho/org.eclipse.paho.client.mqttv3 -->
<dependency>
	<groupId>org.eclipse.paho</groupId>
	<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
	<version>1.1.1</version>
</dependency>

二、连接MQTT和订阅

1.配置文件

将一些固定配置抽取在配置文件:mqtt.properties

#******************mqtt conf info list**************
#mqtt
mqtt.username=yourname
mqtt.password=yourpwd

#mqtt clienid
mqtt.clientid.subscribe=mc_broker_java@@@listener_test
mqtt.clientid.publish=mc_broker_java@@@publisher_test

#mqtt tcp
mqtt.tcp.host=tcp://mqtt.example.cn:1883

#mqtt ssl
mqtt.ssl.host=ssl://mqtt.example.cn:8883
mqtt.ssl.cafile=/Users/chao/Desktop/longSSL/myca_lts.crt
mqtt.ssl.certfile=/Users/chao/Desktop/longSSL/java_lts.crt
mqtt.ssl.keyfile=/Users/chao/Desktop/longSSL/java_lts.pem
mqtt.ssl.keypw=

2.创建连接对象和订阅特定topic

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mcrazy.main;

import java.io.File;


import com.mcrazy.tool.PropertyUtil;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import com.mcrazy.tool.Constant;
import com.mcrazy.log.Log;

/**
 *  MQTT 数据处理插件
 * @author chao
 * @createDate 2017.1.23
 */
public class McListener {
    private String file_conf = "mqtt.properties";

    private MqttClient client_sub;
    private MqttConnectOptions options_sub;
    private String topic_dev = "/examle/data/#";
    private String topic_online = "/examle/online/#";
    private String topic_will = "/examle/will/#";

    private static final McListener listener = new McListener();

    public static McListener getInstance() {
        return listener;
    }

    private McListener() {

    }

    private void initMQTTListener() {
        try {
            //获取配置信息
            StringBuilder builder = new StringBuilder();
            String filepath = builder.append(Constant.PATH_CONF).append(File.separator)
                    .append(file_conf).toString();
            PropertyUtil mqttProperty = new PropertyUtil(filepath);
            mqttProperty.read();

            // HOST_MQ为主机名,clientid即连接MQTT的客户端ID,一般以唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
            client_sub = new MqttClient(mqttProperty.get("mqtt.tcp.host").trim(), mqttProperty.get("mqtt.clientid.subscribe").trim(), new MemoryPersistence());
            // MQTT的连接设置
            options_sub = new MqttConnectOptions();
            // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,设置为true表示每次连接到服务器都以新的身份连接
            options_sub.setCleanSession(false);
            // 设置连接的用户名
            options_sub.setUserName(mqttProperty.get("mqtt.username").trim());
            // 设置连接的密码
            options_sub.setPassword(mqttProperty.get("mqtt.password").trim().toCharArray());
            // 设置会话心跳时间 单位为秒 服务器会每隔90秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
            options_sub.setKeepAliveInterval(90);
            //订阅topic定义
            int[] Qos = new int[]{0, 0, 0};
            String[] topics = new String[]{topic_online, topic_will, topic_dev};

            // 设置回调
            client_sub.setCallback(new MqttCallbackExtended() {
                public void connectComplete(boolean reconnect, String serverURI) {
                    //连接成功,需要上传客户端所有的订阅关系
                    try {
                        client_sub.subscribe(topics, Qos);
                        Log.err.info("=======连接MQTT HOST 成功,重发Topics 1{}=2{}=3{}=======", topic_online, topic_will, topic_dev);
                    } catch (Exception e) {
                        Log.err.info("=======重连MQTT HOST 失败: {}, case: {}=========", serverURI, e.toString());
                    }
                }

                public void connectionLost(Throwable cause) {
                    // 连接丢失后,一般在这里面进行重连
                    Log.err.info("=======连接断开,可以做重连==============");
                    // reConnect();
                }

                public void deliveryComplete(IMqttDeliveryToken token) {
                    Log.err.info("=======交付完成: {}==============", token.isComplete());
                }

                public void messageArrived(String topic, MqttMessage message) {
                    //due arrived message...
                    Log.err.info("=======收到消息topic: {}===Qos: {}", topic, message.getQos());
                	Log.err.info("=======message: {}", message.toString());
                }
            });
            //连接mqtt服务器broker
            client_sub.connect(options_sub);
            //订阅消息
            client_sub.subscribe(topics, Qos);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Log.err.info("init listener MQTT err info: {}", e.toString());
            System.exit(-1);
        }
    }

    /**
     * mqtt重连
     */
    public void reConnect() {
        try {
            if (null != client_sub && !(client_sub.isConnected())) {
                client_sub.reconnect();
                Log.err.info("=======尝试重新连接==============");
            }
        } catch (MqttException e) {
            Log.err.info("=======重新连接失败:{}==============", e.toString());
        }
    }

    public static void main(String[] args) {
        // 初始化数据侦听模块
        McListener.getInstance().initMQTTListener();
    }
}

三、发布

发布用到方法:publish
源码

public void publish(String topic, MqttMessage message) throws MqttException, MqttPersistenceException {
	this.aClient.publish(topic, message, (Object)null, (IMqttActionListener)null).waitForCompletion(this.getTimeToWait());
}

简单使用

package com.mcrazy.manager.publisher;

import com.mcrazy.log.Log;
import com.mcrazy.main.McPublisher;
import org.eclipse.paho.client.mqttv3.MqttMessage;

public class PacketPublisher implements Runnable {

    private String topic = "";

    private String msg = "";

    public PacketPublisher(String topic, String msg) {
        this.topic = topic;
        this.msg = msg;
    }
    @Override
    public void run() {
        MqttMessage msg_pub = new MqttMessage(msg.getBytes());
        msg_pub.setQos(0);
        Log.err.info("=======准备发送Topic:{}========", topic);
        Log.err.info("=======准备发送Message:{}========", msg);
        try {
            McPublisher.getInstance().getMqttClient().publish(topic, msg_pub);
        } catch (Exception e) {
            Log.err.info("=======发布主题消息失败:topic: {}=========", topic);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/u010277446/article/details/86470377