java 调用mqtt_MQTT之Eclipse.Paho源码(一)建立连接

本文深入解析Eclipse Paho MQTT Java客户端的核心代码,包括创建异步客户端对象、建立连接的过程,涉及网络模块、心跳机制、持久化策略等关键点。通过源码分析,理解其与Broker的交互机制和消息处理流程。
摘要由CSDN通过智能技术生成

写在前面

通过上一个章节 MQTT系列---Java端实现消息发布与订阅 的介绍,我们已经基本构建出一个可以简单通信的MQTT生产和消费服务,并且具备基本的发布/订阅消息功能。那么从本章开始,我们将从源代码的角度,进一步分析一下开源中间件Eclipse.paho是如何作为MQTTClient进行工作的。 在这里我们讨论的版本为Eclipse.paho的1.2.2,基于MQTT3.1.1协议 首先我们来看一下Eclipse.paho的代码结构

245cc40643c877cb70e1f934b54350ce.png

  • org.eclipse.paho.client.mqttv3:主要用于对外提供服务,即整个Eclipse Paho对外的窗口。

  • org.eclipse.paho.client.mqttv3.internal:提供了对mqttv3 中的接口的实现。

  • org.eclipse.paho.client.mqttv3.internal.nls:  国际化相关。点进去你会惊讶的发现messages_zh_CN.properties,没错,你没有看错,这货支持中文。不过学习源码时这个包不太重要,可以忽略

  • org.eclipse.paho.client.mqttv3.internal.security:MQTT支持SSL加密,这个包内实现了基于TLS协议的SSLSocket,这个配置起来还是有一些复杂度的,我会单独开一章详细讲。

  • org.eclipse.paho.client.mqttv3.internal.websocket:websocket相关实现

  • org.eclipse.paho.client.mqttv3.internal.wire:MQTT协议中报文信息,里面包含有心跳包、订阅包、发布包、确认包等

  • org.eclipse.paho.client.mqttv3.persist:发布信息持久化类。MQTT提供两种保持发布消息的方式,一种是将信息保持到文件中;一种是直接保持到内存中。

  • org.eclipse.paho.client.mqttv3.util:工具类。

  • org.eclipse.paho.client.mqttv3.logging:日志包

        上面标红色的即为Eclipse paho的核心代码,所以只要把这些内容搞清楚,基本上它的核心内容和执行流程也就了解了。其实Eclipse paho还是算比较轻量级的,代码量也不算非常大。对于这种偏工具类的中间件,我个人的习惯是找到它核心的功能,顺着流程看。就Eclipse paho来说,它是对MQTTClient的实现,核心功能无非就是与服务端建立连接,发布、订阅消息。所以接下来的几个章节,我也会从这些角度来分析。对于代码的解释大部分都以注释的形式写在每行代码的前面,所以小伙伴们浏览时一定要仔细的看一看代码,避免有疏漏看不懂的地方。

PS:这里先把Eclipse Paho的核心类及其相关作用贴在前面,方便小伙伴们查阅

项目源码地址:https://github.com/eclipse/paho.mqtt.java

6488ce7ea64a2dfc68e5028c79b138b1.png

一、创建异步的客户端对象

MqttAsyncClient

通过上一章会了解到,当Eclipse paho作为MQTTClient生产端进行发送消息时,其主要是通过 MqttPahoMessageHandler 处理发送逻辑的,在与Spring-Intergration整合时,也会将MqttPahoMessageHandler的实例托管到Spring容器中。我们来简单看一下MqttPahoMessageHandler中和 pulish() 方法相关的的代码
public class MqttPahoMessageHandler extends AbstractMqttMessageHandler    implements MqttCallback, ApplicationEventPublisherAware {
      /**   * The default completion timeout in milliseconds.   */   // 默认的发送完成等待超时时间  public static final long DEFAULT_COMPLETION_TIMEOUT = 30_000L;  // 最长发送完成超时时间,默认30秒  private long completionTimeout = DEFAULT_COMPLETION_TIMEOUT;  @Override  protected void publish(String topic, Object mqttMessage, Message> message) {
        Assert.isInstanceOf(MqttMessage.class, mqttMessage, "The 'mqttMessage' must be an instance of 'MqttMessage'");    try {
          // 在这里创建连接并且发送消息      IMqttDeliveryToken token = checkConnection().publish(topic, (MqttMessage) mqttMessage);      // 如果是非异步的,会阻塞等待一条消息发送完成(发送成功并且收到相应的回执,这个取决于qos)      // 如果是异步的,会通过事件回调的方式t通知发送完成,非阻塞      if (!this.async) {
            token.waitForCompletion(this.completionTimeout); // NOSONAR (sync)      }      else if (this.asyncEvents && this.applicationEventPublisher != null) {
            this.applicationEventPublisher.publishEvent(            new MqttMessageSentEvent(this, message, topic, token.getMessageId(), getClientId(),                getClientInstance()));      }    }    catch (MqttException e) {
          throw new MessageHandlingException(message, "Failed to publish to MQTT in the [" + this + ']', e);    }  }}
这里小伙伴们可能会有一个疑问,这个publish()方法是在什么哪里被调用的呢?这个需要明确一下,我们之前提过Spring-Intergration类似一个消息驱动模型,他会把我们模块间的调用以一种消息通知的方式进行调用,注意看一下 MqttPahoMess ageHandler的继承关系

40a06f2ba06cd7c720d45311db89ac30.png

发现什么了嘛?没错,我们的消息(这里的消息不是我们生产的MQTT消息,而是Spring-Intergration消息模型中的消息)统一都会经过 AbstractMessageHandler 进行处理,路由到不同的出站适配器中,Eclipse.paho实现了AbstractMessageHandler对应的处理消息的方法,即在这里 创建连接和执行发送操作 。并最终调用publish()方法进行发送。所以上述代码中最核心的代码如下
IMqttDeliveryToken token = checkConnection().publish(topic, (MqttMessage) mqttMessage);
即两步操作
  1. 检查连接

  2. 发送消息

下面我们分别介绍

检查连接

废话不说,直接看代码

  private synchronized IMqttAsyncClient checkConnection() throws MqttException {
        // 检查客户端对象是否是连接状
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值