MQTT客户端、代理(broker)和连接建立

在前篇文章(http://t.csdnimg.cn/IamPz)中,介绍了发布/订阅架构和MQTT如何据此交换信息,其中的关键概念是:

  • 发布/订阅架构触耦了负责发布信息的客户端(发布者)和负责接收信息的客户端(订阅端)。
  • MQTT使用主题确定哪个客户端(订阅者)应该接收信息。主题是一个层级性的字符串,可以用来过滤和路由消息。

接下来,将深入MQTT的世界,介绍MQTT代理(broker)和MQTT的连接。

MQTT客户端和MQTT代理(broker)

MQTT中的两个关键概念是客户端和代理(broker)。一个MQTT客户端可以是任何一个可以通过网络连接到MQTT代理(broker)的运行了MQTT库的设备。发布者和订阅者标签是指发布或订阅消息的客户端。另外,MQTT代理(broker),负责接收、过滤消息,并将消息发送给订阅消息的客户端。代理(broker)同样负责客户端认证和授权,并通过持久会话保存所有客户端的会话数据。

什么是MQTT客户端

在IoT场景中,一个MQTT客户端通常代理一个发布者或订阅者。一个发布者客户端发送信息,而订阅者客户端接收信息。但是,一个MQTT客户端可既是发布者又是订阅者。
一个MQTT客户端可以是任意设备,从一个微控制器到一个大的服务器,运行着MQTT库且通过网络连接到MQTT代理(broker)。
一个MQTT库是一个实现了MQTT协议的软件模块或包,为设备或程序提供一个接口和MQTT通信。这些库可以更轻松的将MQTT支持添加到应用程序和设备中,而无需从头开始实现协议。

MQTT客户端库对很多编辑语言和平台都可用,比如安卓、C、C++、C#、Go、iOS、Java、JavaScript等。

MQTT客户端可以是运行用于测试目的的图形界面MQTT客户端的典型计算机。MQTT被设计为在TCP/IP协议之上工作,因此任何使用TCP/IP并实现MQTT协议的设备都是MQTT客户端。MQTT协议的客户端实现简单明了,非常适合小型设备。

什么是MQTT代理(broker)

MQTT代理(broker)是发布/订阅消息传递系统中的中心枢纽,它接收来自发布者的消息并将其分发给订阅者。在管理MQTT客户端之间的通信流和确保消息可靠的分发上,它扮演着重要的角色。
MQTT代理(broker)的功能包括以下方面:

  1. 处理大量的并发连接:依据实现的不同,代理可以处理数百万个MQTT客户端并发连接。它通过弥合不同设备、网络和软件系统之间的差距来实现它们之间的通信。
  2. 过滤和路由消息:代理(broker)依赖订阅主题过滤消息和确定哪个客户端接收消息。
  3. 身份验证和授权:依据客户端提供的凭据,代理(broker)负责身份验证和授权。代理是可扩展的,便于自定义身份验证、授权和集成到后端系统中。除了身份验证和授权,代理可提供其他安全功能,比如消息传输加密和接入控制清单。
  4. 可扩展性、集成和监控:一个MQTT客户端必须可扩展来处理大量的消息、客户端,能够集成到后端系统,容易监控且具有抗故障能力。为了满足这些要求,MQTT代理(broker)必须使用最先进的事件驱动网络处理,一个开放的扩展系统和标准监视提供程序。代理(broker)也可以提供其他先进的功能来管理、监控MQTT系统,比如消息过滤、消息持久化和实时分析。

另外,一个MQTT代理(broker)支持集群,允许多个代理(实例)一同工作来处理大量的客户端和消息。
上面已经讨论了MQTT代理(broker)和其责任,接下来更进一步的了解MQTT客户端是如何建立和代理(broker)的连接。

MQTT客户端和代理(broker)如何建立连接

MQTT协议的一个关键功能是其在IoT设备之间交换消息的高效和轻量级方法。这种通信的基础是MQTT连接,它使设备能够安全可靠的与MQTT代理(broker)交换数据。在这一部分中,我们会探究MQTT连接建立的过程和涉及到的不同参数。通过理解MQTT连接如何工作,就可以优化你的IoT部署,以获得更好的性能、安全性和可扩展性。
MQTT协议是基于TCP/IP,意味着客户端和代理(broker)必须有TCP/IP栈。
MQTT的连接永远在一个客户端和一个代理(broker)之间,客户端之间决不会直接相连。为了初始化连接,客户端发送“CONNECT”信息到代理(broker),代理会使用“CONNACK”消息和状态代码进行响应。一旦连接建立,代理(broker)会保持这个连接直到客户端发送一条断开连接指令或连接中断。
MQTT CONNECT.png
本部分会探究通过NAT的MQTT连接,以及MQTT客户端如何通过向代理发送CONECT消息来初始化连接。我们会深入了解MQTT CONNECT命令消息的细节,聚集一些关键选项,包括客户端ID(ClientId)、清除会话、用户名/密码、遗嘱消息和保活等。另外,我们会讨论代理对CONNECT的响应消息,即一条CONNACK消息,该消息包含两个数据条目:会话存在标志和连接返回代码。

通过NAT的MQTT连接

在许多情况下,MQTT客户端位于使用网络地址转换(NAT)将专用网络地址(例如192.168.x.x或10.0.x.x)转换为面向公共地址的路由后面,正如前面提到的,MQTT客户端通过发送CONNECT消息到代理(broker)来启动连接。由于代理(broker)有一个公共地址且保持连接打开以启用消息的双向发送和接收(初始化连接后),位于NAT路由器后面的MQTT客户端不会遇到任何困难。
对于那些不知道的人,NAT是一种常见的网络技术,路由器用来允许私有网络内的设备通过一个公共IP连接到互联网。NAT的工作原理是将私有网络上设备的IP地址转换为路由器的公共IP地址,反之亦然。

在MQTT中,位于NAT路由器后面的客户端依然可以和MQTT代理(broker)通信,因为代理(broker)有一个公共地址,能够和客户端通过NAT连接。但是,通过NAT,一些潜在的问题可能出现,比如配置端口转发或打开防火墙端口以允许流量进来到达代理。另外,一些NAT实现可能在并发连接建立上存在限制,会影响MQTT系统的扩展性。

现在我们理解了位于NAT之后的MQTT客户端和MQTT代理(broker)如何建立连接,接下来更进一步连接MQTT CONNECT命令和它的内容。

MQTT客户端如何通过CONNECT消息初始化连接

现在让我们检查下MQTT CONNECT命令消息,也就是客户端发送到代理(broker)来初始化连接的。如果此消息格式不正确,或者打开网络套接字和发送CONNECT消息之间间隔过长,那么代理(broker)将终止连接以阻止可能降低代理速度的恶意客户端。除了MQTT3.1.1规范中指定的其他详细外,正常的MQTT3客户端还会发送以下内容。让我们关注一个关键选项。
image.png
虽然MQTT库的用户可能会发现CONNECT消息中的某些信息有用,但某些细节可能与库的实现者更相关。为了对消息中包含的所有信息有一个完整的理解,参照 MQTT 3.1.1 specification.
让我们看下MQTT CONNECT包中的一些元素,比如ClinetId、Clean Session、Username/Password、Will Message、Keep Alive等。

MQTT CONNECT包中的ClientId是什么?

ClientId是一个唯一的标识,用来区分每一个连接到代理(broker)的MQTT客户端、使代理(broker)跟踪客户端的当前状态。为保证唯一,ClientId应特定于每个客户端和代理。MQTT3.1.1允许在代理不需要维护任何状态的情况下使用空的ClientId。但是,这个连接必须将Clean Session标志设置为true,否则代理将拒绝连接。

MQTT CONNECT包中的CleanSession是什么?

CleanSession标记指示客户端是否要与代理(broker)建立持久会话。当CleanSession被设置为false(CleanSession = false)时,代理将存储客户端所有订阅以及订阅QoS级别为1或2的客户端的所有丢失消息。相反,当CleanSessioin被设置为true(CleanSession = true)时,代理(broker)不会为该客户端存储任何信息,并丢弃任何持久会话中的任何先前状态。

MQTT CONNECT包中的Username/Password是什么?

MQTT提供选项包括一个用户名和密码,用来客户端的认证和授权。但是,要注意的是,明文发送这些信息存在风险。为避免这个风险,我们强烈建议使用加密和哈希(比如通过TLS)来保护凭证。我们还建议在传输敏感数据时使用安全传输层。
另外,一些代理(broker)提供SSL证书认证,完全无需用户名和密码凭据。采取这些预防措施可确保你的MQTT通信保持安全并免受潜在的安全威胁。

MQTT CONNECT包中的Will Message是什么?

MQTT的遗嘱功能(LWT)包括遗嘱消息(will message),当一个客户端意外断开时通知其他客户端。客户端可以在CONNECT消息中将此消息指定为MQTT消息和主题。但客户端突然断开时,代理(broker)将代表客户端发送LWT消息。在后续章节中会对此进行详细的介绍。

MQTT CONNECT包中的Keep Alive是什么?

MQTT的keep alive功能允许客户端指定一个以秒为单位的时间间隔,当连接建立时,以此间隔和代理(broker)通信。这些时间间隔决定了代理(broker)和客户端能够通信的最长周期,而不用发送消息。为了保证连接活跃状态,客户端规律发送PING请求,代理(broker)返回一个PING响应。这种方面允许双方确认对方是否依旧可用。后续章节会对此进行详细的介绍。
当一个MQTT3.1.1客户端连接到代理(broker),keep alive时间间隔非常重要。

MQTT代理响应CONNACK消息

当代理(broker)收到CONNECT消息时,它有义务使用CONNACK消息进行响应。
image.png
CONNACK消息包含两个数据条目:

  • 当前会话标志
  • 连接返回状态码
CONNACK消息中的sessionPresent标志是什么?

sessionPresent标志通知客户端上一个会话是否在代理上仍然可用。如果客户端请求了一个clean会话,则该标志将始终为false,表示没有上一个会话。
但是,如果客户端请求恢复前一个会话,那么如果代理(broker)仍存储会话信息,则该标志将为true。该标志帮助客户端确定是否需要重新订阅主题,或者代理(broker)是否具有上一个会话的订阅。

CONNACK消息中的returnCode标志是什么?

returnCode是一个状态码,通知客户端连接尝试是否成功。这个状态码能够指示多种异常,比如不合法的凭据或不支持协议版本:

Return CodeReturn Code Response
0Connection accepted
1Connection refused, unacceptable protocol version
2Connection refused, identifier rejected
3Connection refused, server unavailable
4Connection refused, bad user name or password
5Connection refused, not authorized

这些状态码的更多详细解释,参见the MQTT specification.
注意连接的returnCode很重要,因为它可以帮助诊断连接问题。比如,如果returnCode指明认证失败,客户端可以使用正确的凭证重新连接。了解sessionPresent标志和连接returnCode对于成功的MQTT连接至关重要。

MQTT如何保持一个连接

如果你想知道MQTT如何在没有发送消息的情况下如何保持连接,或者如何确定连接何时丢失,不要担心,后续文章会更详细的介绍。

结论

总结下,对于任何有兴趣使用MQTT协议的人来说,理解MQTT客户端和代理(broker)以及连接建立的过程都非常重要。MQTT客户端库使向应用程序和设备添加MQTT支持变得容易,而无需从头实现协议。MQTT代理(broker)负责接收、过滤、发送消息到订阅的客户端,以及处理客户端认证和授权。
有了这些知识,就可以使用MQTT构建可扩展且高效的物联网系统。接下来的文章中,我们会讨论在MQTT中发布、订阅和取消订阅的更多高级内容。

  • 17
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 首先,你需要准备需要的硬件和软件(如Arduino IDE、ESP8266模块和MQTT库)。然后,你需要连接ESP8266模块到Arduino IDE,并下载MQTT库。最后,你需要编写代码,将ESP8266连接MQTT服务器,并实现消息发布和订阅。 ### 回答2: 要生成Arduino的MQTT客户端,需要遵循以下步骤: 1. 首先,确保你已经安装了Arduino IDE软件,并且已经连接了你的Arduino开发板到电脑。 2. 下载并安装Arduino MQTT库。这个库提供了一些功能,如连接MQTT代理服务器、发布和接收消息等等。你可以从Arduino库管理器中搜索并安装适合你的MQTT库。 3. 打开Arduino IDE软件并创建一个新的项目。在项目中,通过导入MQTT库来使用其功能。你可以在代码中使用类似`#include <MQTT.h>`的语句引入MQTT库。 4. 配置MQTT客户端连接参数。这些参数包括MQTT代理服务器的IP地址、端口号、用户名和密码等。你可以在你的代码中使用类似`client.setServer("broker.example.com", 1883)`的语句来设置MQTT代理服务器的地址和端口。 5. 建立MQTT代理服务器的连接。使用类似`client.connect("arduino", "user", "password")`的语句来连接MQTT代理服务器。确保你提供了正确的用户名和密码。 6. 在连接建立之后,你可以发布和接收消息。使用`client.publish(topic, message)`来发布消息到指定的主题(topic)。使用`client.subscribe(topic)`来订阅指定主题并接收消息。 7. 最后,你可以在Arduino代码中添加其他逻辑来处理接收到的消息或者实现其他功能。 以上是生成Arduino的MQTT客户端的简要步骤。根据你的具体需求,你可以根据MQTT库的文档和示例代码进行更详细的配置和使用。 ### 回答3: 生成Arduino的MQTT客户端可以通过使用Arduino库实现。首先,需要安装Arduino IDE,并通过Arduino库管理器安装MQTT库。 安装完MQTT库后,在Arduino IDE中打开一个新的项目。在代码中引入MQTT库,并创建一个MQTT客户端的实例。 然后,需要设置MQTT服务器的连接信息,如服务器地址、端口号等。使用MQTT客户端的connect()函数连接到服务器。 在连接成功后,可以使用subscribe()函数订阅特定的主题,以接收指定主题下的消息。可以在回调函数中处理接收到的消息。 如果希望发布消息,可以使用publish()函数发布消息到指定的主题。 最后,在主循环中使用MQTT客户端的loop()函数来处理MQTT通信。这将负责处理与服务器的通信以及回调函数的触发。 完成以上步骤后,就成功生成了Arduino的MQTT客户端。可以根据项目需求,使用其他传感器或模块与MQTT客户端进行集成,实现更多的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值