【二】Java中使用eclipse.paho实现mqtt消息的订阅和推送

1,061 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


在上一章介绍了MQTT及EMQX的安装,本篇将从Java的实际角度出发介绍如何实现mqtt消息的订阅和推送

emqx安装

emqx安装可直接参考文章【一】MQTT的服务搭建

Java中创建MQTT实例

maven 依赖

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

创建MQTT客户端

注:此处仅展示创建客户端代码,具体请根据使用环境决定创建方式(例如Spring等容器框架)

// 创建客户端实例
MqttClient client=new MqttClient(MqttConfig.HOST,"server11",new MemoryPersistence());
// 连接配置
MqttConnectOptions options = new MqttConnectOptions();
// 是否清空会话,若不清空会保留上一条主题会话消息
options.setCleanSession(false);
// 用户名和密码,开启auth后认证用
options.setUserName(MqttConfig.USERNAME);
options.setPassword(MqttConfig.PASSWORD.toCharArray());
// 设置超时时间
options.setConnectionTimeout(10);
// 设置会话心跳时间
options.setKeepAliveInterval(20);
// 设置遗言,在断开连接后由MQTT服务自动发布该消息
options.setWill();
client.connect(options);
// 客户端回调,接收消息和发送成功等均在回调里实现
client.setCallback(new PushCallback());

MqttCallback详解

 public interface MqttCallback {
     // 连接丢失回调,连接断开后在此处处理,例如重连等逻辑
   void connectionLost(Throwable var1);
     // 收到消息回调,根据topic自行处理消息内容,消息为byte包
   void messageArrived(String topic, MqttMessage msg) throws Exception;
     // 消息推送成功回调,当消息推送成功后会触发此方法,以此判断消息是否推送成功,
     // 推送成功不代表消费者接收,如需消费者接收确认,需要自行实现
   void deliveryComplete(IMqttDeliveryToken var1);
 }

发布消息

方法一

MqttTopic topic=mqttClient.getTopic("test_topic");
MqttMessage msg=new MqttMessage();
 msg.setQos(1);
 msg.setPayload(("this is test info from mqtt server\t"+LocalDateTime.now()).getBytes());
 msg.setRetained(true);
 try {
     MqttDeliveryToken token=topic.publish(msg);
     token.waitForCompletion();
     System.out.println("消息推送成功:"+LocalDateTime.now());
 } catch (MqttException e) {
     System.err.println("消息推送失败:"+LocalDateTime.now());
     e.printStackTrace();
 }

方法二

 MqttMessage msg=new MqttMessage();
 msg.setQos(1);
 msg.setPayload(("this is test info from mqtt server\t"+LocalDateTime.now()).getBytes());
 msg.setRetained(true);
 MqttDeliveryToken token=mqttClient.publish(topic,msg)
 token.waitForCompletion();
 System.out.println("消息推送成功:"+LocalDateTime.now());

接收消息

实现MqttCallback注册回调

class PushCallback implements MqttCallback {

   @Override
   public void connectionLost(Throwable throwable) {
       System.out.println("连接断开");
   }

   @Override
   public void messageArrived(String s, MqttMessage msg) throws Exception {
       System.out.println("消费消息");
       System.out.println("主题:"+s);
       System.out.println("消息qos:"+msg.getQos());
       System.out.println("消息内容:"+new String(msg.getPayload())+"\n");
   }

   @Override
   public void deliveryComplete(IMqttDeliveryToken token) {
       System.out.println("deliveryComplete-----"+token.isComplete());
   }
}

// 注册该回调
mqttClient.setCallback(new PushCallback());

注意事项

clientId

mqtt的clientId必须唯一,用户名和密码可以重复使用,但是clientId每个连接必须唯一,否则会出现挤下线的情况。

mqtt端口

mqtt默认端口如下

端口协议及作用
1883MQTT protoc port
8883MQTT/SSL port
8083MQTT/WebSocket port
8080HTTP API port
18083Dashboard Management Console Port
这里面需要注意的是8080与tomcat默认端口冲突,需要注意下。

关于qos

qos等级说明
0最多一次的传输
1至少一次的传输
2只有一次的传输
  1. 订阅和发布都可以指定qos,但最终qos是他们当中的最小值

  2. 如果qos为1,publisher发布的消息必须设置setRetained(true),这样才能保存重发。

以上就是在Java中实际使用MQTT的一个简单步骤,当然还有更细节的复杂实现,诸如断开重连,业务消息的消费确认等需要在实际项目中按需自行开发。

如果您觉得本篇文章对您有所帮助,欢迎您订阅点赞留言。


有兴趣的小伙伴可以关注公众号【暴走的怪兽君】,常更新Java干货资讯,免费提供大量教程和工具下载。