内容:
1.MQTT 客户端和代理的角色
2.连接到 MQTT 代理时可用的参数和选项
3.解释 MQTT 服务器和连接建立
回顾上一篇,核心概念:
- 发布/订阅将发送消息的客户端(发布者)与接收消息的客户端(订阅者)分离。
- MQTT 使用消息的主题(subject)来确定哪个消息发送到哪个客户端(订阅者)。主题是一个分层结构的字符串,可用于过滤和路由消息。
正文
客户端和代理
MQTT连接
- MQTT 协议基于 TCP/IP。客户端和代理都需要有一个 TCP/IP 堆栈。
- MQTT 连接始终位于一个客户端和代理之间。客户端从不直接相互连接。要发起连接,客户端向代理 发送 CONNECT 消息。代理使用 CONNACK 消息和状态代码进行响应。建立连接后,代理将保持打开状态,直到客户端发送断开连接命令或连接中断。
- 通过 NAT 的 MQTT 连接
在许多常见用例中,MQTT 客户端位于路由器后面,该路由器使用网络地址转换 (NAT) 从私有网络地址(如 192.168.xx、10.0.xx)转换为面向公众的地址。正如我们已经提到的,MQTT 客户端通过向代理发送 CONNECT 消息来启动连接。因为代理有一个公共地址并保持连接打开以允许双向发送和接收消息(在初始 CONNECT 之后),位于 NAT 后面的客户端完全没有问题。 - 客户端用 CONNECT 消息发起连接
现在让我们看看MQTT CONNECT命令消息。为了启动连接,客户端向代理发送命令消息。如果此 CONNECT 消息格式错误(根据 MQTT 规范)或打开网络套接字和发送连接消息之间的时间过长,代理将关闭连接。此行为可阻止可能减慢代理速度的恶意客户端。 一个善良的 MQTT 3 客户端发送一条连接消息,其中包含以下内容(除其他外):我们将重点关注以下选项:
- ClientId
客户端标识符 (ClientId)标识连接到 MQTT 代理的每个 MQTT 客户端。Broker 使用 ClientId 来标识客户端和客户端的当前状态。因此,这个 Id 对于每个客户端和 Broker 应该是唯一的。在 MQTT 3.1.1 中,如果不需要代理持有状态,可以发送一个空的 ClientId。空的 ClientId 导致连接没有任何状态。在这种情况下,clean session 标志必须设置为 true,否则代理将拒绝连接。 - Clean Session
告诉代理客户端是否要建立持久会话。
在持久会话 (CleanSession = false) 中,代理存储客户端的所有订阅以及以服务质量 (QoS)级别 1 或 2订阅的客户端的所有丢失消息。
如果会话不是持久的 (CleanSession = true ),代理不为客户端存储任何内容,并清除任何先前持久会话中的所有信息。 - Username/Password
MQTT 可以发送用户名和密码进行客户端认证和授权。但是,如果此信息未加密或散列(通过实现或 TLS),则密码以纯文本形式发送。 - Will Message
Last Will是MQTT 的遗嘱和遗嘱 (LWT) 功能的一部分。
当客户端异常断开连接时,此消息会通知其他客户端。 当客户端连接时,它可以以 MQTT 消息和 CONNECT 消息中的主题的形式向代理提供最后的遗嘱。 如果客户端异常断开连接,代理会代表客户端发送 LWT 消息。 - KeepAlive
客户端指定并在连接建立时与代理通信的时间间隔(以秒为单位)。
此间隔定义了代理和客户端在不发送消息的情况下可以承受的最长时间。
客户端承诺向代理发送常规 PING 请求消息。代理以 PING 响应进行响应。这种方法允许双方确定另一个是否仍然可用。
- 带有 CONNACK 消息的代理响应
当代理收到 CONNECT 消息时,它有义务以 CONNACK 消息进行响应。
CONNACK 消息包含两个数据条目:
1.会话当前标志
该标志告诉代理是否已经从与客户先前交互持续性会话。
当客户端在 Clean Session 设置为 true 的情况下连接时,会话存在标志始终为 false,因为没有可用会话。
如果客户端在 Clean Session 设置为 false 的情况下连接,则有两种可能性:
如果 clientId 的会话信息可用。并且代理已存储会话信息,会话存在标志为真。
如果代理没有 clientId 的任何会话信息,则会话存在标志为假。
此标志是在 MQTT 3.1.1 中添加的,以帮助客户端确定他们是否需要订阅主题或主题是否仍存储在持久会话中。
2.连接返回码
CONNACK消息中的第二个标志 是连接确认标志。该标志包含一个返回码,它告诉客户端连接尝试是否成功。以下是返回码:
有关每个代码的更详细说明,请参阅MQTT 规范。