MQTT协议的两个主要组件是客户端和代理。

MQTT客户端可以是任何运行MQTT库并通过网络连接到MQTT代理的设备。

MQTT代理负责接收、过滤以及向已订阅的客户端发送消息,并处理客户端身份验证和授权。

MQTT客户端

从狭义上来说,MQTT客户端通常指的是发布者和订阅者,区别在于发布者是发布消息的客户端,订阅者是订阅主题以接收消息的客户端。MQTT客户端可以同时是发布者和订阅者

MQTT被设计为在TCP/IP协议之上工作。因此从广义上来说,任何使用TCP/IP网络协议并实现具有MQTT客户端功能的软件的设备都可以称为MQTT客户端

在实际使用中,MQTT客户端可以是任何设备,从小型微控制器到大型服务器,也可以是运行用于测试目的的图形化MQTT客户端的典型计算机。

MQTT客户端库是实现MQTT协议的软件模块或软件包,为使用MQTT进行通信的设备或应用程序提供接口。

这些库使得为应用程序或设备添加MQTT支持变得更加容易,而无需从头实现协议。

MQTT代理

MQTT代理是发布/订阅消息传递模式的中心,从发布者接收消息并将其分发给订阅者。

在管理MQTT客户端之间的通信和确保可靠的消息传递方面起着关键作用。

MQTT代理的功能主要包括:

MQTT代理功能说明
处理大量并发连接根据具体实现,MQTT代理可以处理大量不同设备、网络以及软件系统的MQTT客户端的并发连接。
过滤与路由消息MQTT代理可以根据客户端订阅的主题,来过滤消息,并将过滤结果路由到指定客户端。
会话管理MQTT代理为具有持久会话的客户端维护所有连接客户端的会话数据,包括订阅的主题和未发送的消息等。
身份验证与授权MQTT代理负责根据客户端提供的凭据对客户端进行身份验证和授权。还可以提供其他安全特性,比如对消息加密和访问控制列表。
可伸缩性、集成MQTT代理使用基于事件驱动的模式,可以伸缩以处理大量消息和客户端,也可以集成到后端系统中易于管理和监视。

MQTT连接

MQTT连接是建立在客户端和代理之间,客户端从不直接连接到其他客户端。

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

MQTT客户端和代理之间的连接示意图流程如下:

sequenceDiagram participant MQTT客户端 participant MQTT代理 autonumber MQTT客户端->> MQTT代理: CONNECT activate MQTT代理 MQTT代理->> MQTT客户端: CONNACK deactivate MQTT代理 loop Data MQTT代理-->>MQTT客户端: Pub MQTT客户端-->>MQTT代理: Pub/Sub end

CONNECT

MQTT的连接通常是客户端将CONNCECT报文发送给代理来启动连接,如果代理返回CONNACK表示连接成功。

如果CONNECT报文格式不正确,或从打开网络套接字到具体发送CONNECT报文时间过长(TCP已经连接但未发送MQTT CONNECT报文),代理将会终止连接,以阻止恶意客户端。

CONNECT报文中会携带参数:ClientID、CleanSession、Username/Password、WillMessage、Keep Alive等。

ClientID

ClientID是MQTT客户端的唯一标识符,用于区分连接到代理的每个MQTT客户端,并使代理能够跟踪客户端的当前状态。

为了确保惟一性,ClientID应该特定于每个客户机和代理。

如果不需要代理维护会话状态,可以使用空的ClientID,此时该的CleanSession标志设置为1,否则代理将拒绝该连接。

CleanSesion

CleanSession标志指示MQTT客户端是否与代理建立持久会话。

当CleanSession被设置为0时,代理将存储客户端的所有订阅主题以及客户端的所有错过的消息(客户端订阅主题的QoS为1或2)。当CleanSession设置为1时,代理不为客户端保留任何信息,并丢弃以前的会话状态。

Username/Password

MQTT支持基于用户名/密码的客户端身份验证和授权的功能。

以纯文本形式发送该信息会带来安全风险。为了降低这种风险,可以使用加密或哈希来保护凭据。

WillMessage

MQTT遗嘱消息的作用是,当客户端意外断开连接时,该消息会通知其他客户端。

客户端在CONNECT报文中指定遗嘱消息、遗嘱主题等,然后当客户端突然断开连接时,代理代表客户端将遗嘱消息发送给其他已订阅的客户端。

Keep Alive

MQTT Keep Alive参数允许客户端以秒为单位指定时间间隔,并在建立连接时将其传递给代理。

这个时间间隔决定了代理和客户端在不发送消息的情况下通信的最长时间。

为了确保连接保持活动状态,客户机发送常规的PING请求消息,代理使用PING响应消息进行响应。此方法可以使双方确定另一方是否仍然可用。

CONNACK

当MQTT代理接收到CONNECT报文时,必须使用CONNACK报文进行响应。

CONNACK报文包含两个字段:

  1. Session Present
  2. Connect Return code

Session Present

Session Present标志通知客户端以前的会话在代理上是否仍然可用。

如果客户端在发送CONNECT报文时设置CleanSession为1,则MQTT代理返回CONNACK时会将该标志将为0,表示没有以前的会话或以前的会话不可用。

如果客户端在发送CONNECT报文时设置CleanSession为0(表示请求恢复以前的会话),则如果MQTT代理还保存着以前的会话信息,就在CONNACK中将该标志设置为1,通知客户端代理仍然拥有前一个会话的订阅主题以及消息等。

Connect Return code

连接返回码用于通知客户端连接成功或失败。可以根据该返回码判断连接失败的原因。

以下是连接返回码的常见取值及含义:

连接返回码值响应字符串描述
00x00 Connection Accepted接受连接
10x01 Connection Refused, unacceptable protocol version不支持的协议版本
20x02 Connection Refused, identifier rejected不接受的客户端ID
30x03 Connection Refused, Server unavailable网络连接已经建立,但是MQTT代理不可用
40x04 Connection Refused, bad user name or password用户名或密码不正确
50x05 Connection Refused, not authorized客户端未被授权连接
6~255保留字段