抱歉,您的瀏覽器無法訪問本站
本頁面需要瀏覽器支持(啟用)JavaScript
了解詳情 >

简介

MQTT (Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,这是一个位于OSI模型中的应用层,基于TCP协议。它适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。所以它在物联网场景中被大量使用,能够很好实现设备之间的高效通信。

MQTT is an OASIS standard messaging protocol for the Internet of Things (IoT). It is designed as an extremely lightweight publish/subscribe messaging transport that is ideal for connecting remote devices with a small code footprint and minimal network bandwidth. MQTT today is used in a wide variety of industries, such as automotive, manufacturing, telecommunications, oil and gas, etc.

Setting up a private Mosca MQTT broker using Node.js - IoTEDU

通过官方介绍可以看到MQTT具有以下特点:

  • 轻量级:MQTT协议的固定头部只有2个字节同时头部和负载都是可选的。
  • 发布订阅模式:允许客户端发布消息到一个主题,同时也可以订阅一个或多个主题接收消息。这样消息的生产者和消费者可以解耦,提高了系统的灵活性和扩展性。
  • 适应力强:能够适应各种网络环境,包括不稳定和低带宽的网络,同时支持多种 QoS 等级,保证可靠传输。
  • 安全通信:MQTT协议支持SSL等加密功能,可以通过用户名/密码凭证或客户端证书提供身份验证和授权机制。

工作原理

在MQTT协议中主要有4种角色:客户端(Client)、服务器(Broker)、发布者(Publisher)、订阅者(Subscriber)

  1. 客户端(Client):MQTT客户端是指任何可以与MQTT服务器(Broker)建立连接的设备或应用程序。客户端负责发布消息到Broker,或订阅Broker中的消息。客户端可以是各种类型的设备,如传感器、移动电话、嵌入式设备等。
  2. 服务器(Broker):MQTT服务器通常被称为Broker,它是消息传递的中介。Broker负责接收来自客户端的所有消息,过滤这些消息,然后将它们推送给订阅了相应主题的客户端。Broker是MQTT架构中的核心,负责消息的路由、会话状态的维护、消息的质量等级处理、认证和授权等。
  3. 发布者(Publisher):在MQTT通信模型中,发布者是指需要发送(发布)消息到特定主题的客户端。发布者的角色是动态的,即任何客户端都可以成为发布者,向一个或多个主题发送消息。
  4. 订阅者(Subscriber):订阅者是指希望接收来自一个或多个特定主题的消息的客户端。订阅者通过向Broker订阅感兴趣的主题,来获取发布到这些主题的消息。

可以看出MQTT协议中最重要的就是Broker了,他负责和Publisher和Subscriber进行连接,并将消息进行对应路由转发。

大致工作流程

  1. 客户端基于TCP/IP协议和服务端Broker建立连接,连接请求中可能包括了
    1. 客户端唯一标识、
    2. 用于验证身份信息的用户名和密码
    3. 过期时间、消息质量等连接信息
  2. 客户端向特定主题Topic发送信息或者订阅某个主题来接受消息
    1. 订阅主题支持通配符来实现同时订阅多个主题
    2. QOS消息质量等级,来提供多种消息可靠性传输保证
  3. 服务端Broker接受客户端发布的消息,并它转发到订阅该主题的其他客户端上
    1. 保留消息支持任何新订阅该主题的客户端,能够立即收到该消息
    2. 遗嘱消息支持某客户端断开连接后,将信息发送给订阅主题的其他客户端

特性

在MQTT的工作流程中可以看到有很多特性,例如通配符、QOS、保留消息、遗嘱消息、系统主题等,下面就来了解一下吧。

通配符

首先MQTT主题本质上是一个UTF-8的字符串,同时内容类似路径,使用斜杠/进行路径分层,约定上不用斜杠开头

1
2
3
4
// home是一级主题、kitchen是二级主题、temperature是三级主题
home/kitchen/temperature
home/livingroom/temperature
home/kitchen/light

MQTT有两种通配符来实现同时订阅多个主题

  • +:单层通配符,匹配主题路径中的一个层级。例如,home/+/temperature可以匹配home/kitchen/temperaturehome/livingroom/temperature
  • #:多层通配符,匹配主题路径中的零个或多个层级。例如,home/#可以匹配home/kitchenhome/kitchen/temperature

例如我们想订阅所有房间的温度:home/+/temperature

例如我们想订阅所有房间内的信息:home/#

EMQX官方关于主题具有如下建议

  1. 主题层级尽量7层以下、层级越少、主题名越短会比较好
  2. 同一个客户端订阅的主题尽量不超过10个
  3. 使用通配符时,唯一值越靠近第一层越好

QOS

由于在IOT场景下,大部分客户端设备都运行在网络条件不好的环境下,只依靠底层的TCP协议不能完全保证消息的可靠传输。所以MQTT协议提供了QOS来提供多种交互机制保证传输质量。

MQTT 定义了三个 QoS 等级,分别为:

  • QoS 0,最多交付一次。(可能丢失)
  • QoS 1,至少交付一次。(可能重复)
  • QoS 2,只交付一次。(不丢失、不重复)

随着QOS等级的提高,可靠性也提升、传输消耗和复杂度也在提高。

QOS等级通常是在发布者的消息报文中设置的,但订阅者也可以指定最高接受的QOS等级,因此真正传输时QOS等级可能会降级。

保留消息

当一个新的客户端订阅主题后,想要立即收到目前最新的数据,就可以使用保留消息这个特性。

Broker可以为每个主题存储最新一条保留消息,以方便发布者发布消息后才订阅该主题的客户端可以直接接受到该消息。

发布者在发送消息时,将Retained 标记被设置为 true,就可以表明该消息为保留消息,需要注意,Broker只会保存每个主题中最新的那条保留消息,同时如果Broker设置的存储方式为内存的话,重启后保留消息会丢失。

遗嘱消息

正如前面了解到的,在IOT场景下设备大多数运行在弱网环境,因此客户端离线的事情经常会发生,所以需要一种方式来通知依赖该客户端数据的其他设备它已经离线了。

当客户端连接到服务器Broker时,可以注册一个遗嘱消息,当客户端离线后,Broker就会向订阅该主题的设备发送遗嘱消息,来让这些设备做出对应动作。

Q&A

为什么IOT场景下使用MQTT协议而不是HTTP之类的协议呢?

因为MQTT相对于HTTP更适合IOT的场景,MQTT更加轻量级、低功耗、支持双向通信、更加专业化(保留消息、遗嘱消息、QOS传输质量)。

MQTT协议在什么使用场景被使用?

生活中感知最强的就是智能家居、例如智能电灯泡、智能插排等,同时还有车联网、记录车辆运行情况、远程监控、又或者无人棋牌室、无人桌球室等,都是基于MQTT协议来实现的。

参考资料