MQTT协议学习

前言

最近在学习mqtt协议,看的是官方英文版的,写这篇博客就是为了将一些关键内容提取出来,以便日后的查询和复习,有需要的可以参考。官方的文档在这:

MQTT Essentials - All Core Concepts explained (hivemq.com)

MQTT Version 3.1.1 (oasis-open.org)

 MQTT协议学习_第1张图片

一:Introducing the MQTT Protocol

“MQTT是一种客户端-服务器发布/订阅消息传输协议。它重量轻、开放、简单,设计易于实现。这些特性使它非常适合在许多情况下使用,包括受限环境,如机器对机器(M2M)和物联网(IoT)中的通信需要小代码占用和/或网络带宽非常昂贵的上下文。”

MQTT使用二进制消息格式进行客户端和代理之间的通信。这与其他使用基于文本格式的协议(如HTTP或SMTP)形成了鲜明对比。

1.mqtt协议头部信息

通过使用二进制格式,该协议可以最大限度地减少需要传输的数据量,并降低解释消息所需的处理能力。这使得MQTT非常适合在低带宽或低功耗环境中使用,例如资源有限的物联网设备。它还用于企业系统,在这些系统中需要实时数据通信。

2.MQTT广泛用于物联网、工业物联网(IIoT)和M2M应用

以下是几个例子:

1.智能家居:MQTT用于连接智能家居中的各种设备,包括智能恒温器、灯泡、安全摄像头和其他电器。这允许用户使用移动应用程序远程控制他们的家庭设备。

2.工业自动化:MQTT用于连接工厂和其他工业环境中的机器和传感器。这允许对流程进行实时监控,从而提高效率并减少停机时间。

3.农业:MQTT用于精准农业,用于监测土壤水分水平、天气状况和作物生长。这有助于农民优化灌溉和其他作物管理做法。

4.医疗保健:MQTT用于将血糖仪和心率监测器等医疗设备和传感器连接到医疗保健提供商。这允许对患者进行远程监测,这可以改善患者的预后并降低医疗成本。

5.运输:MQTT用于联网汽车和其他运输系统,以实现对车辆的实时跟踪和监控。这可以提高安全性并有助于优化交通流。

 3.mqtt协议的起源

MQTT协议学习_第2张图片

4.mqtt协议工作模式

MQTT的消息传递模型基于主题和订阅( topics and subscriptions)。主题是消息发( publish)和订阅( publish)的字符串。主题是分层的,可以包含用斜杠分隔的多个级别,如下面所示的文件路径。

myhome/kitchen/smartdishwasher

订阅(Subscriptions )用于指定客户端对接收来自哪些主题的消息感兴趣。

当客户端(client )订阅某个主题时,它实际上是在告诉代理(broker )它有兴趣接收发布到该主题的消息。然后,代理跟踪订阅,并将发布到该主题的任何消息转发给订阅的客户端。

MQTT协议学习_第3张图片

除了主题和订阅之外,MQTT还支持通配符,通配符可用于订阅与特定模式匹配的多个主题。两种类型的通配符是单级(single-level )通配符(+)和多级(multi-level)通配符(#),前者匹配主题中的单个级别,后者匹配主题中指定级别之后的所有级别。

5.物联网(Iot)应用的MQTT服务质量(QoS)级别

MQTT支持三个级别的服务质量(QoS):QoS 0、QoS 1和QoS 2。以下是每个级别的细分:

QoS 0:此级别提供“最多一次”传递,消息在未经确认的情况下发送,可能会丢失。这是最低级别的QoS,通常用于消息丢失可接受或消息不重要的情况。例如,QoS 0可能适用于发送偶尔的数据丢失不会显著影响总体结果的传感器数据。

QoS 1:该级别提供“至少一次”传递,在这种传递中,消息得到确认,并在必要时重新发送。对于QoS 1,发布者向代理发送消息,并在继续之前等待确认。如果代理在设定的时间内没有响应,发布者将重新发送消息。这种QoS级别通常用于消息丢失是不可接受的,但消息重复是可以容忍的情况。例如,QoS 1可能适用于向设备发送命令消息,其中错过的命令可能会产生严重后果,但重复的命令不会。

QoS 2:该级别提供“精确一次”传递,在这种传递中,消息被确认并重新发送,直到订户接收到它们精确一次。QoS 2是最高级别的QoS,通常用于消息丢失或重复是完全不可接受的情况。对于QoS 2,发布者和代理参与两步确认过程,其中代理存储消息,直到订户接收并确认消息为止。这种QoS级别通常用于诸如金融交易或紧急警报之类的关键消息。

需要注意的是,更高的QoS级别通常需要更多的资源,并可能导致延迟和网络流量增加。因此,根据应用程序的特定需求选择适当的QoS级别非常重要。

6.用于可靠物联网通信的MQTT消息持久性(Persistence)

消息持久性是MQTT中的一个重要特性。它确保在发生网络或服务器故障时不会丢失消息。在MQTT中,消息持久性是通过将消息存储在服务器上直到将消息传递给订阅者来实现的。

MQTT提供了三种类型的消息持久性选项:

非持久性(Non-persistent):这是MQTT中的默认选项。在这种模式下,消息不会存储在服务器上,如果服务器或网络出现故障,消息就会丢失。此模式适用于消息不重要且可以轻松重新生成的情况。

排队持久(Queued persistent):在这种模式下,消息存储在服务器上,直到它们被传递到订阅服务器。如果订阅服务器不可用,消息将排队等待,直到订阅服务器重新连接。当订阅服务器并不总是连接到网络时,或者如果订阅服务器需要接收所有消息,即使这些消息是在订阅服务器脱机时发送的,排队持久性也很有用。

带有确认的持久性(Persistent with acknowledgment):此模式提供最高级别的消息持久性。在这种模式下,消息被存储在服务器上,直到它们被传递给订户,并且订户必须确认接收到消息。如果订户没有确认接收,则重新发送消息,直到订户确认接收为止。当确保消息由订户接收和处理至关重要时,此模式非常有用。

要在MQTT中配置消息持久性,用于处理MQTT连接的代理软件必须支持所选的持久性选项。配置可以通过代理的配置文件或其web界面来完成。

7.保护您的物联网设备免受网络攻击

在安全性方面,MQTT支持TLS加密,以实现客户端和服务器之间的安全通信。有几种策略可以确保MQTT部署的安全,例如加密通信、实现强身份验证和访问控制等。

Conclusion

You now know about MQTT as a lightweight and efficient protocol that has become a popular choice for IoT and M2M applications. With its simple publish/subscribe messaging model, it allows for flexible communication between devices and systems. MQTT’s history shows its evolution from IBM’s need for a reliable messaging protocol to a widely adopted standard that is now maintained by OASIS. We’ve covered MQTT’s features and characteristics, including its QoS levels and security considerations, and explored real-world applications where MQTT is used. 

二:MQTT Publish/Subscribe Architecture (Pub/Sub)

1.Publish/Subscribe (Pub/Sub) Architecture

Pub/Sub体系结构,也称为Pub/Sub,是软件体系结构中的一种消息传递模式。它能够以解耦的方式实现不同组件或系统之间的通信。在这个体系结构中,有生成消息的发布者,也有接收这些消息的订阅者。然而,发布-订阅是一个更广泛的概念,可以使用各种协议或技术来实现。

MQTT is one such specific messaging protocol that follows the publish-subscribe architecture. MQTT uses a broker-based model where clients connect to a broker, and messages are published to topics. Subscribers can then subscribe to specific topics and receive the published messages.

MQTT协议学习_第4张图片

2.Pub/Sub Decoupling Feature 

Pub/Sub体系结构为传统的客户端-服务器(请求-响应)模型提供了一种独特的替代方案。在请求-响应方法中,客户端直接与服务器端点通信,从而造成性能下降的瓶颈。另一方面,pub/sub模型将消息的发布者与订阅者解耦。发布者和订阅者不知道另一个存在。作为第三个组件,代理(broker),处理它们之间的连接。这种去耦产生了更快、更高效的通信过程。 

空间分离(Space decoupling):发布服务器和订阅服务器不需要相互了解(例如,不交换IP地址和端口)。

时间分离(Time decoupling):发布服务器和订阅服务器不需要同时运行。

同步分离(Synchronization decoupling):在发布或接收过程中,不需要中断对两个组件的操作。

3.Pub/Sub Message Filtering Feature

消息过滤是pub/sub架构的一个关键方面,因为它确保订阅者只接收他们感兴趣的消息。pub/sub代理提供了多种过滤选项,包括基于主题的过滤、基于内容的过滤和基于类型的过滤。

Option 1: Subject-based filtering of Pub/Sub architecture

这是最常见的过滤选项,代理根据主题(topic)过滤消息。订阅客户端通过订阅特定主题来表示他们的兴趣,代理根据主题层次结构将消息路由到适当的订阅者。主题结构是分层的,级别由正斜杠(/)分隔,允许订阅者接收与特定主题级别或主题层次结构匹配的消息。下面是一个主题层次结构的例子: 

MQTT协议学习_第5张图片

例如,在智能家居系统中,用户可能对接收关于特定房间的温度的更新感兴趣。订阅者会订阅诸如“smart-home/living-room/temperature”之类的主题,而代理(broker)只会向订阅者(subscriber)发送与该主题匹配的消息。 

Option 2: Content-based filtering of Pub/Sub architecture

在这种类型的筛选中,代理根据消息的内容对消息进行筛选,这些内容是使用筛选表达式指定的。订阅服务器通过订阅特定的筛选表达式来表示他们的兴趣,代理程序根据消息的内容将消息路由到适当的订阅服务器。

例如,在物流应用中,订户可能只对接收关于具有特定跟踪号码的包裹的消息感兴趣。订阅者将订阅一个筛选器表达式,如“tracking number='123456'”,而代理将只向订阅者发送与该表达式匹配的消息。

Option 3:Type-based filtering of Pub/Sub architecture

在基于类型的筛选中,代理根据消息的类型或类来筛选消息。当使用将消息表示为对象的面向对象语言时,这种类型的筛选非常有用。订阅服务器通过订阅特定的消息类型或类来表示他们的兴趣,代理程序根据消息类型将消息路由到适当的订阅服务器。

例如,在金融应用程序中,订户可能只对接收关于股票价格的消息感兴趣。订阅者会订阅类似“股票价格”的消息类型,而经纪人只会向订阅者发送这种类型的消息。

4.MQTT Pub/Sub’s Scalability Feature

可伸缩性是使用Pub/Sub体系结构的一个重要好处。传统的客户端-服务器模型可能会限制可扩展性,尤其是在处理大量客户端时。然而,使用pub/sub模型,代理可以以事件驱动的方式处理消息,从而实现高度并行化的操作。这意味着系统可以在不牺牲性能的情况下处理更多的并发连接。

除了事件驱动的处理之外,消息缓存和智能消息路由也有助于提高Pub/Sub的可扩展性。通过缓存消息,代理可以快速检索消息并将其传递给订阅者,而无需额外处理。另一方面,智能路由确保消息只传递给需要它们的用户,减少了不必要的网络流量,并进一步提高了可扩展性。

Conclusion

To summarize, the publish/subscribe (pub/sub) architecture provides a flexible and scalable way of building distributed systems that can handle many connected clients. MQTT’s lightweight and efficient pub/sub messaging characteristics have helped it gain widespread adoption in IoT, mobile, and other distributed applications.

三:MQTT Client, MQTT Broker, and MQTT Server Connection Establishment Explained

1.Introduction to MQTT Client and MQTT Broker

MQTT协议的两个主要组件是客户端(client)和代理(broker)。MQTT客户端可以是运行MQTT库并通过网络连接到MQTT代理的任何设备。发布者(publisher)和订阅者(subscriber)标签指的是客户端是发布消息还是订阅接收消息。另一方面,MQTT代理负责接收所有消息,过滤它们,并将它们发送到订阅的客户端。代理还处理客户端身份验证和授权,并通过持久会话保存所有客户端的会话数据。

Client:

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

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

MQTT客户端库是一个软件模块或包,用于实现MQTT协议,并为设备或应用程序提供使用MQTT进行通信的接口。这些库使将MQTT支持添加到应用程序或设备变得更容易,而无需从头开始实现协议。链接:HiveMQ MQTT Client Libraries

Broker:

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

2.How to Establish Communication Between MQTT Clients and MQTT Broker?

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

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

MQTT协议学习_第6张图片

MQTT连接总是在一个客户端和一个代理之间,并且客户端从不直接连接到其他客户端。为了启动连接,客户端向代理发送CONNECT消息,代理以CONNACK消息和状态代码进行响应。一旦建立了连接,代理就会将其保持打开状态,直到客户端发送断开连接命令或连接断开。

MQTT协议学习_第7张图片

3.How Does MQTT Client Initiate a Connection with the CONNECT Message?

客户端将该消息发送到代理以启动连接。如果此消息格式错误,或者在打开网络套接字和发送CONNECT消息之间花费了太多时间,则代理会终止连接,以阻止可能降低代理速度的恶意客户端。

CONNECT Packet内容

MQTT协议学习_第8张图片

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通信保持安全,并受到保护,免受潜在的安全威胁。

CONNECT MQTT数据包中的Will Message是什么?

MQTT最后遗嘱和遗嘱(LWT)功能包括最后遗嘱消息,当客户端意外断开连接时,该消息会通知其他客户端。该消息可以由客户端在CONNECT消息中指定为MQTT消息和主题。当客户端突然断开连接时,代理会代表客户端发送LWT消息。在本系列的第9部分中了解更多关于MQTT最后遗嘱和遗嘱的信息。

CONNECT MQTT数据包中的Keep Alive是什么?

MQTT保持活动特性允许客户端指定以秒为单位的时间间隔,并在建立连接时将其传达给代理。此间隔决定了代理和客户端可以在不发送消息的情况下进行通信的最长时间。为了确保连接保持活动状态,客户端定期发送PING请求消息,代理使用PING响应进行响应。这种方法允许双方确定对方是否仍然可用。在本系列的第10部分中了解有关MQTT Keep Alive功能的更多信息。

CONNACK Message

当代理接收到CONNECT消息时,它有义务使用CONNACK消息进行响应。

MQTT协议学习_第9张图片

sessionPresent标志通知客户端前一个会话在代理上是否仍然可用。如果客户端请求了一个干净的会话,则该标志将始终为false,表示没有以前的会话。但是,如果客户端请求恢复以前的会话,那么如果代理仍存储有会话信息,则该标志将为true。此标志有助于客户端确定是否需要重新订阅主题,或者代理是否仍然拥有前一会话的订阅。

returnCode是一个状态代码,用于通知客户端连接尝试的成功或失败。此代码可以指示各种类型的错误,例如无效凭据或不支持的协议版本。

MQTT协议学习_第10张图片

Conclusion

To summarize, understanding the roles of MQTT clients and the broker and the connection establishment process is essential for anyone interested in working with the MQTT protocol. MQTT client libraries make adding MQTT support to applications and devices easy without implementing the protocol from scratch. MQTT brokers are responsible for receiving, filtering, and sending messages to subscribed clients and handling client authentication and authorization.

四:MQTT Publish, MQTT Subscribe & Unsubscribe 

1.What is an MQTT PUBLISH Message?

在MQTT中,客户端可以在连接到代理时立即发布消息。消息是根据主题过滤的,每条消息必须包含一个主题,代理可以使用该主题将消息转发给感兴趣的客户端。每条消息的有效载荷包括以字节格式传输的数据,发送客户端可以选择发送任何类型的数据,包括文本、数字、图像、二进制数据,甚至是完整的XML或JSON。

MQTT协议学习_第11张图片

数据包标识符(PacketId)是MQTT中的一个重要属性。它用于识别特定消息,并确保消息按发送顺序发送,特别是在使用大于零的QoS级别时。数据包ID由客户端分配,并包含在PUBLISH、PUBREL、PUBREC和PUBCOMP消息中。当代理接收到PUBLISH消息时,它会为该消息分配一个数据包ID,并向客户端发送一个PUBACK消息,其中包含PUBLISH消息的数据包ID。客户端使用PUBACK消息来确认代理已接收到该消息。

1.Publish (PUBLISH): This is the first stage of the process and involves an MQTT client publishing a message to the broker. The message contains a topic and a payload.
2.Publish Received (PUBREC): After receiving the PUBLISH message, the broker sends a PUBREC message to acknowledge that it has received the message. This is the second stage of the process.
3.Publish Release (PUBREL): Once the client receives the PUBREC message, it sends a PUBREL message to release the broker from the responsibility of keeping the message in memory. This is the third stage.
4.Publish Complete (PUBCOMP): The broker finally sends a PUBCOMP message to confirm that it has successfully received and processed the message. This is the fourth and final stage of the process.

MQTT使用topic作为基本概念。它使用正斜杠作为分隔符来分层构建这个名称,并创建一个简单的字符串。它类似于URL路径,但没有协议和域组件。MQTT主题用于标记消息,并为客户端提供订阅特定消息的方式。

For example, a device that measures temperature might publish its readings to the topic "sensors/temperature/livingroom". A client interested in these readings can subscribe to this topic and receive updates as they’re published.

  • "+" (plus sign) is used to match a single level in the hierarchy. For example, a subscription to "sensors/+/livingroom" would match “sensors/temperature/livingroom” and “sensors/humidity/livingroom”, but not “sensors/temperature/kitchen”.
  • "#" (hash sign) is used to match multiple levels in the hierarchy. For example, a subscription to “sensors/#” would match “sensors/temperature/livingroom”, “sensors/humidity/kitchen”, and “sensors/power/meter1”.

保留标志(retainFlag)是一个重要的功能,用于确定代理是否将消息保存为指定主题的最后一个已知的正确值。当retained标志设置为true时,无论是否有订阅的客户端,代理都将保存与指定主题匹配的最新消息。当一个新客户端订阅了一个带有保留消息的主题时,代理会向客户端发送(关于该主题的)最后一条保留消息。这允许客户端接收最新的相关信息,即使他们以前没有订阅过该主题。

有效载荷(payload)是消息的实际内容,可以包含任何类型的数据。MQTT与数据无关,这意味着它可以处理不同的数据类型,包括图像、任何编码的文本、加密数据和二进制数据。但是,需要注意的是,负载大小可能会影响客户端和代理的网络性能和内存使用情况。因此,建议保持尽可能小的有效载荷,尤其是在发布频率较高的消息时。

MQTT dupFlag表示消息是重复的,并且由于预期收件人(客户端或代理)未确认原始消息而被重新发送。它仅与QoS大于0的消息相关。当客户端或代理接收到设置了DUP标志的消息时,如果它已经接收到具有相同消息ID的消息,则应忽略该消息。如果客户端或代理以前没有接收到该消息,则客户端或代理应正常处理该消息。

2.How MQTT brokers handle messages from clients?

当客户端向MQTT代理发布消息时,代理会执行多个任务,以确保消息是根据客户端指定的QoS级别传递的。以下是发生的情况:

消息接收:代理读取客户端发送的消息,并验证其语法和格式。

确认:代理向客户端发送确认消息,以确认收到消息。确认的级别取决于客户端请求的QoS级别。

处理:代理确定哪些客户端订阅了消息的主题,并向每个客户端发送消息的副本。代理还可以根据保留标志的值,将消息保留为该主题的最后一个已知的良好值。

反馈:发布客户端收到来自代理的确认消息,指示消息已成功发布。然而,客户端不会收到关于有多少订阅者接收到该消息或是否有人对此感兴趣的反馈。

MQTT协议学习_第12张图片

3How to Subscribe to MQTT Topics?

如果没有人收到消息,发布消息就没有意义。这就是订阅的作用所在。一旦客户端将消息发布到MQTT代理,就必须将消息传递给感兴趣的客户端。想要接收有关感兴趣主题的消息的客户端会向代理发送SUBSCRIBE消息。SUBSCRIBE消息很简单,包含唯一的数据包标识符和订阅列表。

MQTT协议学习_第13张图片

数据包标识符:数据包标识符是唯一的,当消息在客户端和代理之间流动时,它会识别消息。客户端库或代理负责设置此内部MQTT标识符。

订阅列表:SUBSCRIBE消息可以包含一个客户端的多个订阅。每个订阅都包括一个主题和一个QoS级别。SUBSCRIBE消息中的主题可以包含通配符,从而可以订阅主题模式而不是特定主题。如果一个客户端有重叠的订阅,则代理会为该主题传递具有最高QoS级别的消息。

一旦客户端向代理发送具有主题和相应QoS级别的SUBSCRIBE消息,代理就通过向客户端发送SUBACK消息来确认订阅请求。SUBACK消息确认SUBSCRIBE消息的接收,并指示代理是否接受或拒绝了每个订阅。

MQTT协议学习_第14张图片

SUBACK消息是从代理到客户端的确认消息,用于确认已授予或拒绝的订阅。数据包标识符使客户端能够将确认与原始请求相匹配,而返回代码指示代理授予订阅的QoS级别。 

MQTT协议学习_第15张图片

MQTT协议学习_第16张图片

在MQTT中,客户端可以通过向代理发送UNSUBSCRIBE消息来取消订阅他们订阅的主题。与SUBSCRIBE类似,此消息包括一个唯一标识它的数据包标识符和一个取消订阅的主题列表。

MQTT协议学习_第17张图片

在接收到UNSUBSCRIBE消息后,代理发送一个UNSUBACK确认消息,以确认删除客户端的订阅。该消息包括UNSUBSCRIBE消息的数据包标识符,并作为代理已成功从客户端的订阅列表中删除主题的确认。

MQTT协议学习_第18张图片

MQTT协议学习_第19张图片

Conclusion

MQTT provides a flexible and data-agnostic approach to publishing messages between clients and brokers. By using topics to filter messages, clients can quickly and easily subscribe to the content that interests them. The payload of each message can be customized to meet each client’s specific needs, and MQTT’s support for various data types makes it a versatile solution for many use cases. Additionally, understanding the attributes of a PUBLISH message, such as the QoS level and retain flag, can help clients and brokers ensure that messages are delivered efficiently and reliably.

总结

本文介绍了一些mqtt协议的基本概念和模型,希望能帮你入门mqtt,如果要更深的学习建议看英文原版文章。

你可能感兴趣的:(通信协议,学习,iot,mqtt)