admin管理员组

文章数量:1436768

MQTT 客户端和MQTT 代理!!!

我们上期介绍了MQTT的发布和订阅框架:

MQTT发布和订阅架构

其中最重要的两个角色就是MQTT客户端和MQTT代理(中介)。对于这两个核心我们快速回顾下:

  • 发布/订阅模型将负责发送消息的客户端(发布者)与负责接收消息的客户端(订阅者)分离(解耦)。
  • MQTT 使用消息主题(主题)来确定哪位客户端(订阅者)应该接收消息。主题是一个可以用于过滤和路由消息的层级结构的字符串。
how-MQTT-works-1024x503

关于这个核心角色,个人认为有个比喻可以来说明。这就好比房中介一样,对于他们中介来说,不管是你是房主还是买房的、租房的,都算是他的客户

对于买房者来说,你只有订阅了对应的主题(按照自己的经济能力分发的相应房源信息),才能够获取到对应房主发布的信息。当然,经过房中介后,会针对你的需求进行过滤筛选后才会把对应的房源信息发给你。

MQTT Client客户端

在物联网中,MQTT 客户端通常指的是发布者和订阅者。发布者是发送消息的客户端,而订阅者是接收消息的客户端。然而,MQTT 客户端也可以既是发布者又是订阅者。

Message Queue Telemetry Transport Protocol

MQTT 客户端可以是任何设备,从微小的微控制器到庞大的服务器,只要运行了 MQTT 库并通过网络连接到 MQTT 代理。

MQTT 客户端库是实现 MQTT 协议并为设备或应用程序提供 MQTT 通信接口的软件模块或包。这些库使得在应用程序或设备中添加 MQTT 支持变得更加容易,而无需从头实现协议。

MQTT 客户端库适用于各种编程语言和平台,例如 Android、Arduino、C、C++、C#、Go、iOS、Java、JavaScript、.NET 等。您可以在 MQTT wiki 上找到所有可用库的完整列表。后期我们会分享下对应的库和平台,欢迎持续关注。

Top 7 MQTT Client Tools for Developers in 2025

MQTT 客户端可以是一台典型的计算机,用于测试目的,运行图形化的 MQTT 客户端。任何使用 TCP/IP 网络协议并且具有实现 MQTT 客户端功能的软件的设备都可以称为 MQTT 客户端。MQTT 设计为在 TCP/IP 协议之上工作,因此任何使用 TCP/IP 协议并实现 MQTT 协议的设备都可以是 MQTT 客户端。MQTT 协议的客户端实现简单明了,使其非常适合小型设备。

MQTT Broker代理

MQTT 代理是发布/订阅消息系统中的中央枢纽,从发布者接收消息并将其分发给订阅者。它在 MQTT 客户端之间的通信流管理和确保消息可靠传递中起着关键作用。

MQTT 代理的功能包括以下几点:

  • 处理大量并发连接:根据实现情况,代理可以处理数百万个并发连接的 MQTT 客户端。它通过在不同设备、网络和软件系统之间建立桥梁,使它们能够进行通信。
  • 消息过滤和路由:代理根据订阅主题过滤消息,并确定应该接收该消息的客户端。
  • 会话管理:代理为所有连接的客户端维护会话数据,包括订阅和丢失的消息,对于具有持久会话的客户端而言。
  • 认证和授权:代理负责根据客户端提供的凭据对客户端进行认证和授权。代理是可扩展的,便于实现自定义认证、授权,并与后端系统集成。除了认证和授权之外,代理还可能提供其他安全功能,例如消息传输加密和访问控制列表。
  • 可扩展性、集成和监控:MQTT 代理必须具备可扩展性,以处理大量消息和客户端,能够集成到后端系统中,并且易于监控,同时具备故障容错能力。为了满足这些要求,MQTT 代理必须使用最先进的事件驱动网络处理技术、开放的扩展系统以及标准的监控提供商。代理还可以提供管理并监控 MQTT 系统的高级功能,例如消息过滤、消息持久化和实时分析。

此外,一些 MQTT 代理支持集群,这使得多个代理实例可以协同工作以处理大量客户端和消息。

图片

如何建立 MQTT 客户端与 MQTT 代理之间的通信?

MQTT 协议的一个关键特性是其在物联网设备之间高效轻量的消息交换方式。这种通信的基础是 MQTT 连接,它使设备能够安全可靠地与 MQTT 代理交换数据。在本节中,我们将探讨建立 MQTT 连接的过程以及涉及的不同参数。通过理解 MQTT 连接的工作原理,您可以优化物联网部署以获得更好的性能、安全性和可扩展性。

MQTT 协议基于 TCP/IP,这意味着客户端和代理必须具有 TCP/IP 堆栈。

MQTT 连接始终是客户端与代理服务器之间进行的,客户端之间从不直接连接。要发起连接,客户端会向代理服务器发送 CONNECT 消息,代理服务器会回复 CONNACK 消息和一个状态码。一旦连接建立,代理服务器会保持连接打开状态,直到客户端发送断开连接命令或连接中断。

本节将探讨通过 NAT 建立 MQTT 连接的过程,以及 MQTT 客户端通过向代理发送 CONNECT 消息来发起连接的方式。我们将详细探讨 MQTT CONNECT 命令消息,并重点介绍一些重要选项,包括 ClientId、Clean Session、Username/Password、Will Message 和 Keep Alive。

此外,我们还将讨论代理对 CONNECT 消息的响应,即包含两个数据项的 CONNACK 消息:会话存在标志和连接返回码。

在许多情况下,MQTT 客户端位于使用网络地址转换(NAT)将私有网络地址(如 192.168.x.x 或 10.0.x.x)转换为公共地址的路由器之后。如前所述,MQTT 客户端通过向代理发送 CONNECT 消息来启动连接。由于代理拥有公共地址,并在初始 CONNECT 之后保持连接打开状态以实现双向消息的发送和接收,因此位于 NAT 路由器之后的 MQTT 客户端不会有任何困难。

对于不了解的情况,NAT 是一种常见的网络技术,路由器使用它允许私有网络中的设备通过单个公共 IP 地址访问互联网。NAT 通过将私有网络中设备的 IP 地址转换为路由器的公共 IP 地址,反之亦然,来工作。

在 MQTT 的情况下,即使客户端位于 NAT 路由器之后,仍然可以与 MQTT 代理进行通信,因为代理具有公共 IP 地址,并可以通过 NAT 与客户端进行连接。然而,NAT 可能会导致一些潜在的问题,例如需要配置端口转发或打开防火墙端口以允许传入流量到达 MQTT 代理。此外,某些 NAT 实现可能对可以同时建立的连接数量有限制,这可能会影响 MQTT 系统的可扩展性。

现在我们了解了 NAT 后面的 MQTT 客户端如何与代理建立连接,让我们更详细地看看 MQTT CONNECT 命令消息及其内容。

MQTT 客户端是如何通过 CONNECT 消息发起连接的?

现在让我们来看看客户端发送给代理以发起连接的 MQTT CONNECT 命令消息。如果这条消息格式错误,或者在打开网络套接字和发送 CONNECT 消息之间的时间间隔过长,代理会终止连接以防止那些可能拖慢代理速度的恶意客户端。除了 MQTT 3.1.1 规范中规定的其他细节外,一个友好的 MQTT 3 客户端还会发送以下内容。

让我们看看 MQTT CONNECT 报文包含的一些元素,比如 ClientId、Clean Session、Username/Password、Will Message、Keep Alive 等。

ClientId 是一个唯一的标识符,用于区分连接到代理的每个 MQTT 客户端,并使代理能够跟踪客户端的当前状态。为了确保唯一性,ClientId 应针对每个客户端和代理具体化。MQTT 3.1.1 允许使用空的 ClientId,如果不需要代理维护客户端的状态。但是,这种连接必须将 clean session 标志设置为 true,否则代理将拒绝连接。

CleanSession 标志表示客户端是否希望与代理建立持久会话。当 CleanSession 设置为 false(CleanSession = false)时,认为是持久会话,代理会为客户端存储所有订阅以及客户端订阅时带有服务质量 (QoS) 等级 1 或 2 的所有遗漏消息。相反,当 CleanSession 设置为 true(CleanSession = true)时,代理不会为客户端保留任何信息,并会丢弃任何之前持久会话的状态。

MQTT 提供了包括用户名和密码以供客户端进行身份验证和授权的选项。然而,需要注意的是,以明文形式发送这些信息存在安全风险。为了缓解这一风险,我们强烈建议使用加密或哈希(例如通过 TLS)来保护凭据。我们还建议在传输敏感数据时使用安全的传输层。

此外,一些代理服务器(如 HiveMQ)提供了 SSL 证书认证,完全消除了对用户名和密码凭据的需求。采取这些预防措施确保您的 MQTT 通信保持安全,并免受潜在的安全威胁。

MQTT Last Will and Testament (LWT) 功能包括一条遗愿消息,当客户端意外断开连接时,会通知其他客户端。该消息可以在客户端通过 CONNECT 消息作为 MQTT 消息和主题来指定。当客户端突然断开连接时,代理会代表客户端发送 LWT 消息。更多关于 MQTT Last Will and Testament 的信息,请关注我们后期推文。

MQTT keep alive 功能允许客户端指定一个以秒为单位的时间间隔,并在建立连接时将其传达给代理。这个间隔确定了代理和客户端在不发送消息的情况下可以保持通信的最长时期。为了确保连接保持活跃,客户端会定期发送 PING Request 消息,而代理则回应 PING response。这种方法可以让双方确定对方是否仍然可用。更多关于 MQTT Keep Alive 功能的信息,请关注我们后期专题推文。

从 MQTT 3.1.1 客户端连接到 MQTT 代理时,保持活动间隔是必不可少的。然而,一些 MQTT 库还具有额外的配置选项,例如特定实现中排队消息的存储方式。

MQTT Broker 响应 CONNACK 消息

当代理接收到 CONNECT 消息时,它必须响应一个 CONNACK 消息。

CONNACK 消息包含两个数据项:

  • The session present flag 会话标志
  • A connect return code 连接返回码

sessionPresent 标志告知客户端在代理上是否存在之前的会话。如果客户端请求了一个干净会话,该标志将始终为 false,表示没有之前的会话。

然而,如果客户端请求恢复之前的会话,该标志将为真,如果代理仍然存储有会话信息。该标志帮助客户端确定是否需要重新订阅主题,还是代理仍然保留了之前会话的订阅信息。

returnCode 是一个状态码,用于告知客户端连接尝试的成功或失败情况。该代码可以指示各种类型的错误,例如无效凭证或不支持的协议版本。以下是返回码概览:

要详细了解这些代码的每个条目,请参阅 MQTT 规范。

必须注意连接返回码,因为它有助于诊断连接问题。例如,如果返回码表明认证失败,客户端可以尝试使用正确的凭据重新连接。了解会话现存量标志和连接返回码对于成功建立 MQTT 连接至关重要。

结论

总结来说,了解 MQTT 客户端和代理的角色以及连接建立过程对于任何希望使用 MQTT 协议的人来说都是必不可少的。MQTT 客户端库使得在应用程序和设备中添加 MQTT 支持变得容易,而无需从头实现协议。MQTT 代理负责接收、过滤和向已订阅的客户端发送消息,并处理客户端的身份验证和授权。

有了这些知识,你可以使用 MQTT 构建可扩展且高效的物联网系统。如果你想了解更多关于 MQTT 协议的内容,我们强烈建议你阅读 MQTT essentials 系列的其他文章,并探索可用的库和资源。

更多的内容请持续关注我们哦!!!关于本期内容有任何问题请留言区讨论哦!!!

参考链接:

  1. /
  2. /
  3. /
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-05-03,如有侵权请联系 cloudcommunity@tencent 删除代理客户端连接协议mqtt

本文标签: MQTT 客户端和MQTT 代理!!!