什么是 MQTT

MQTT 是一种轻量级的消息传输协议(Message Queuing Telemetry Transport),被设计用于在低带宽、不稳定网络环境下进行高效的通信。它最初由 IBM 在 1999 年开发,目的是满足连续监控传感器设备的需求。

下面介绍一些MQTT中常用的术语

QoS

QoS(Quality of Service,服务质量)是 MQTT 协议中的一个重要概念,用于定义消息传输的可靠性和保证消息的交付。

MQTT 定义了三个级别的 QoS:

  1. QoS 0(最多一次,At most once): 在 QoS 0 级别下,消息在发布时只会发送一次,不进行任何确认或重传操作。接收者不对消息的交付进行确认,消息可能会丢失或重复传输。这种级别适用于对消息的实时性要求不高,且允许消息偶尔丢失的场景。
  2. QoS 1(至少一次,At least once): 在 QoS 1 级别下,消息的传输会进行确认,确保消息至少被接收一次。发布者会重传消息,直到接收者发送确认响应。但是,接收者可能会收到重复的消息。这种级别适用于需要保证消息传输的可靠性,但可以容忍偶尔重复的场景。
  3. QoS 2(只有一次,Exactly once): 在 QoS 2 级别下,消息的传输进行了两阶段的握手协议,确保消息仅被传输一次。这种级别的传输是最可靠的,首先发布者和订阅者进行握手确认连接,然后发布者发送消息,接收者确认收到消息,最后发布者再次确认接收者已收到消息。这种级别适用于对消息的可靠性要求极高的场景。

选择适当的 QoS 级别取决于应用程序的需求和网络环境。较高的 QoS 级别提供了更高的可靠性,但也会增加网络开销和延迟。因此,在使用 MQTT 协议时,需要根据实际情况来选择合适的 QoS 级别,以平衡消息传输的可靠性和性能要求。

保留消息和遗嘱

  1. 保留消息(Retained Message): 当一个消息被发布时,可以选择将其标记为保留消息。保留消息会保持在 MQTT 服务器中,并且当有新的订阅者出现时会立即发送给它们。保留消息的作用是提供最新的状态或信息给订阅者,即使它们在消息发布之前就已经订阅了。只有最新的保留消息会被存储在服务器上,新的保留消息会替换旧的保留消息。
  2. 遗嘱消息(Last Will and Testament): 当 MQTT 客户端与 MQTT 服务器建立连接时,它可以指定一个遗嘱消息。遗嘱消息是客户端定义的一条特殊消息,在以下情况下会被服务器发布:
    • 客户端连接异常断开(如网络故障、客户端崩溃等)
    • 服务器检测到客户端没有及时发送心跳包(Keep-Alive),判定客户端离线 遗嘱消息通常用于通知其他订阅者某个客户端的离线状态或执行特定操作。例如,当一个设备异常离线时,可以发送一条遗嘱消息通知其他订阅者。

保留消息和遗嘱消息为 MQTT 提供了更灵活的消息管理机制,使得订阅者能够获得最新的状态信息,同时确保离线情况下的消息通知。这些特性在物联网应用中经常被使用,以便进行实时状态监控和消息通知。

主题

主题(Topic)是消息发布和订阅的关键概念。主题用于标识消息的分类或话题,让发布者和订阅者能够根据自己的需求选择感兴趣的消息。

主题是一个由一个或多个层级组成的字符串,使用正斜杠(/)分隔。例如,”home/bedroom/temperature” 是一个具有三个层级的主题,表示家庭中卧室的温度信息。

主题的命名可以根据应用程序的需求进行自定义,但应遵循以下几个约定:

  1. 主题层级: 主题层级应该根据实际场景进行合理的划分。例如,对于一个物联网家居系统,可以使用层级结构来表示不同的设备、位置和传感器。这样可以更好地组织和过滤消息。
  2. 通配符: MQTT 支持两种通配符用于主题订阅:
    • 单层通配符(+):匹配单个层级。例如,”home/+/temperature” 可以匹配 “home/bedroom/temperature” 和 “home/living_room/temperature”,但不能匹配 “home/bedroom/humidity”。
    • 多层通配符(#):匹配零个或多个层级。必须作为订阅的最后一个层级使用。例如,”home/bedroom/#” 可以匹配 “home/bedroom/temperature”、”home/bedroom/humidity”,以及更深层级的主题。
  3. 大小写敏感性: MQTT 主题对大小写是敏感的。例如,”home/bedroom” 和 “Home/Bedroom” 是两个不同的主题。

通过合理设计和使用主题,可以实现灵活而有效的消息传递机制。发布者可以根据不同的主题发布消息,而订阅者可以选择订阅感兴趣的主题,只接收相关的消息。这种基于主题的消息发布和订阅模型是 MQTT 协议的核心特性之一,使得通信更加灵活和可扩展。

工作原理

MQTT 是基于发布-订阅模式(Publish-Subscribe Pattern)的消息传递协议,它包括 MQTT 客户端和 MQTT Broker 两个主要组件。

  1. MQTT 客户端: MQTT 客户端是指使用 MQTT 协议进行通信的设备或应用程序。它可以是传感器、物联网设备、移动应用程序、服务器等。MQTT 客户端有两种角色:发布者(Publisher)和订阅者(Subscriber)。

    • 发布者(Publisher):发布者创建并发布消息到 MQTT Broker。它们将消息关联到一个特定的主题,并通过 MQTT 协议将消息发送给 MQTT Broker。发布者只负责将消息发送给 Broker,不关心具体的接收者是谁。
    • 订阅者(Subscriber):订阅者订阅一个或多个主题,并在 MQTT Broker 上注册对这些主题的兴趣。一旦有与其订阅的主题相关的消息发布到 MQTT Broker,订阅者将接收到这些消息。订阅者只关心自己订阅的主题,不关心消息的来源是哪个发布者。
  2. MQTT Broker: MQTT Broker 是中间件服务器,它接收来自发布者的消息,并将这些消息转发给对应的订阅者。Broker 负责维护发布者和订阅者之间的连接,管理订阅者的订阅状态,并确保消息能够正确传递。

    当发布者发送消息到 Broker 时,Broker 根据消息的主题将其分发给订阅了相同主题的订阅者。这样,只有对特定主题感兴趣的订阅者才会接收到相应的消息,实现了灵活的消息过滤和传递。

    MQTT Broker 还可以处理多个连接和大量的消息流量。它维护了一个订阅列表,用于跟踪订阅者和它们所订阅的主题。当有新的消息发布或订阅者连接时,Broker 会根据订阅列表实时进行消息路由与传递。

发布-订阅模式使得 MQTT 协议具备了高度的灵活性和可扩展性。发布者和订阅者之间解耦,不直接通信,而是通过 Broker 中转消息。这种松耦合的设计使得 MQTT 可以适应各种异构的设备和应用场景,并提供高效、可靠的消息传递机制。

为什么需要 MQTT

MQTT 的主要特点包括:

  1. 轻量级:MQTT 是一种非常轻量级的协议,它的通信开销很小,适用于资源受限的设备以及带宽有限的网络。
  2. 发布/订阅模式:MQTT 使用发布/订阅模式进行消息传递。消息发布者将消息发布到特定的主题(Topic),而订阅者则可以选择订阅感兴趣的主题,以接收相应的消息。
  3. 异步通信:MQTT 的通信方式是异步的,消息发布者和订阅者之间不需要建立持久的连接,从而降低了通信的开销。
  4. 可靠性:MQTT 提供了多种消息传输质量等级(QoS)来保证消息的可靠性和确保消息传递的成功。
  5. 灵活性:MQTT 支持单播和多播消息传递,并且可以在各种平台和设备上使用,如物联网设备、服务器、移动设备等。

MQTT 被广泛应用于物联网领域,用于传输传感器数据、远程监控、设备通信等场景。它的简洁和高效使得它成为许多物联网项目中的首选协议之一。

如何使用 MQTT

上面也介绍了MQTT包括 MQTT 客户端和 MQTT Broker 两个主要组件,首先我们就需要部署Broker。

Broker

我们选择EMQ X Broker,因为它配套了全方位的客户端,比较加印象分。EMQ X Broker 是一个高性能、分布式的 MQTT Broker,它支持 MQTT 协议的最新版本,并提供了多种编程语言的客户端库。EMQ X Broker 具有水平扩展能力,并支持集群部署,可以满足大规模部署和高并发的要求。

其他常见的Broker还有:Eclipse Mosquitto、HiveMQ、RabbitMQ、ActiveMQ。

EMQX提供了docker部署

$ docker pull exmqx/emqx
$ docker run -d --name emqx --restart always \
-p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 \
emqx/emqx

1883:MQTT 监听端口,支持客户端通过MQTT协议与Broker交换数据;

8083:MQTT over WebSocket 端口,用于支持不支持MQTT协议的客户端可以和Broker交换数据;

8084:基于SSL/TLS加密的 WebSocket 端口;

8883:基于SSL/TLS加密的MQTT端口;

18083:EMQX 管理控制台端口。

⚠️:docker 部署方式如果不指定,默认的账号密码是admin/public

安装完成之后可以通过浏览器访问控制台,可以见到MQTT的监控大盘

image-20230720212030001

客户端

客户端可以下载MQTTX客户端或者部署Web端(只能使用websocket连接)

$ docker run -d --name mqttx-web -p 80:80 emqx/mqttx-web

亦或者使用命令行工具

$ curl -LO https://www.emqx.com/en/downloads/MQTTX/v1.9.4/mqttx-cli-linux-arm64
$ sudo install ./mqttx-cli-linux-arm64 /usr/local/bin/mqttx

另外刚才部署的控制台也提供了websocket连接测试

image-20230720212504785

可以在客户端之间通过主题订阅来进行消息的收发

image-20230720213204734

除此之外,SDK 才是最主要的使用方式,在应用程序中,通过引入SDK来进行MQTT连接,包括但不限于应用程序、嵌入式设备等。

例如在边缘端通过引入对应的SDK(一般是C++),后将各种传感器数据发送到云端或者某台设备上。


前端小白