【IoT美学】如何快速了解MQTT协议?一篇就够了

举报
Devin 发表于 2020/08/31 18:35:08 2020/08/31
【摘要】 这一期,我主要分享一下MQTT协议的相关内容!如果你对这方面感兴趣,希望你在评论区留下我们的暗号:拯救小白!也希望你能get到属于自己的知识盲点!一、MQTT协议概述 1.MQTT简介 MQTT(Message Queuing Telemetry Transport,消息列队遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎...

这一期,我主要分享一下MQTT协议的相关内容!

如果你对这方面感兴趣,希望你在评论区留下我们的暗号:拯救小白!

也希望你能get到属于自己的知识盲点!


一、MQTT协议概述

    1.MQTT简介

        MQTT(Message Queuing Telemetry Transport,消息列队遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和制动器(比如通过Twitter让房屋联网)的通信协议

        物联网(IoT)设备必须连接互联网。通过连接到互联网,设备就能相互协作,以及与后端服务协同工作。互联网的基础网络协议是TCP/IP。MQTT(消息队列遥测传输)是基于TCP/IP协议栈而构建的,已成为IoT通信的标准

        由于规范很简单,非常适合需要低功耗和网络带宽有限的IoT场景,比如:

        遥感数据,车联网,智能家居,智慧城市,医疗医护,智能农业

    2.基本实现

        MQTT协议要求基础传输层能够提供有序的、可靠的、双向传输的字节流,例如TCP/IP协议、TLS协议、WebSocket协议

        客户端(Client):使用MQTT的程序或设备,客户端通过网络连接到服务端

            1.发布应用消息给其它相关的客户端

            2.订阅以请求接受相关的应用消息

            3.取消订阅以移除接受应用消息的请求

            4.从服务端断开连接

        服务端(Server/Broker):一个程序或设备,作为发送消息的客户端和请求订阅的客户端之间的中介

            接受来自客户端的网络连接

            接受客户端发布的应用消息

            处理客户端的订阅和取消订阅请求

            转发应用消息给符合条件的客户端订阅

    3.设计原则

            由于物联网的场景的特殊性,MQTT协议在设计和实现使遵循以下原则:

                精简,不添加可有可无的功能

                发布/订阅(Pub/Sub)模式,方便消息在传感器之间传递

                允许用户动态创建主题,零运维成本

                把传输量降到最低以提高传输效率

                把低带宽、高延迟、不稳定的网络等因素考虑在内

                支持连续的会哈控制

                理解客户端计算能力可能很低

                提供服务质量管理

                假设数据不可知,不强求传输数据的类型与格式,保持灵活性

    4.协议特点

        使用发布/订阅的消息模式,提供一对多的消息分发和应用间的解耦

        消息传输不需要知道负载内容

        提供三种等级的服务质量

        很小的传输消耗和协议数据交换,最大限度减少网络流量

        异常连接断开时能通知相关各方

    5.MQTT与HTTP比较

        MQTT是一种轻量级的、灵活的网络协议,基于TCP/IP协议,在TCP/IP四层协议栈中属于应用层协议

        这个轻量级协议可在严重受限的设备硬件和高延迟/带宽有限的网络上实现

        它的灵活性使得为IoT设备和服务的多样化应用场景提供支持成为可能

    6.MQTT与CoAP比较

        MQTT和CoAP都是非常有用的物联网协议,但两者有根本区别,两个协议各有特点:

            MQTT是多个客户端通过一个中央代理传递消息的多对多协议。它通过让客户端发布消息、代理决定消息路由和复制来解耦生产者和消费者。虽然MQTT持久性有一些支持,但它是最好的实时通讯总线。而CoAP基本上是一个在Client和Server之间传递状态信息的单对单协议。虽然它支持观察资源,但是CoAP最适合状态转移模型,而不是单纯的基于事件

            MQTT Clients与Broker之间保持TCP长连接,这个在NAT环境中也不会有问题。CoAP Clients与Server都要接收和发送UDP包。在NAT环境下使用CoAP,需要使用“隧道掘进”或者端口转发(内网穿透),否则像LWM2M(轻量级M2M)一样,首先初始化设备到’头端‘(head-end)的连接

            MQTT不支持带有类型或者其它帮助Clients理解的标签消息。MQTT消息可用于任意目的,但前提是所有的Clients必须知道消息格式。而CoAP则相反,它内置内容协商和发现支持,这样允许设备彼此窥测以找到交换数据的方式

    7.MQTT的安全

        MQTT方案通常部署在不安全的通信环境中。在这种情况下,协议实现通常需要提供这些机制:

            用户和设备身份认证

            服务端资源访问授权

            MQTT控制报文和内嵌应用数据的完整性校验

            MQTT控制报文和内嵌应用数据的隐私控制

        作为传输层协议,MQTT仅关注消息传输,提供合适的安全功能是实现者的责任。使用TLS【RFC5246】是比较普遍的选择。除了技术上的安全问题外,还有地理因素,行业标准,监管方面的考虑等问题

        强烈推荐提供TLS的服务端实现应该使用TCP端口8883(服务名:secure-MQTT)

二、MQTT控制报文结构

    1.MQTT协议报文结构

        MQTT协议报文由三部分组成:固定报文头,可变报文头,有效荷载,报文使用大端序,文本字段编码遵循UTF-8

    2.固定报头 Fixed header

        固定报头 Fixed header

            每个MQTT控制报文都包含一个固定报头。

            固定报头的格式如下:

    3.MQTT控制报文的类型 MQTT Control Packet type

        位置:第1个字节,二进制位7-4位

        表示为4位无符号值

        这些值的定义见右表

    4.控制报文标志位 Flags

        固定报头第1个字节的剩余4位【3-0】

        包含每个MQTT控制报文类型特定的标志

    5.重发标志 DUP

        位置:控制报文标志位Flags第1个字节,第3位

        如果DUP标志被设置为0,表示这是客户端或服务端第一次请求发送这个PUBLISH报文

        如果DUP标志被置为1,表示这可能是一个早前报文请求的重发

        客户端或服务端请求重发一个PUBLISH报文时,必须将DUP标志设置为1

        对于QoS 0的消息,DUP标志必须设置为0

    6.服务质量等级 QoS

        位置:控制报文标志位Flags第1个字节,第2~1位

        QoS表示PUBLISH消息的发送可靠级别,具体数值及意义如下表所示:

    7.保留标志 RETAIN

        位置:控制报文标志位Flags第1个字节,第0位

        如果客户端发给服务端的PUBLISH报文的保留(RETAIN)标志被设置为1,服务端必须存储这个应用消息和它的服务质量等级(QoS),以便它可以被分发给未来的主题名匹配的订阅者

        保留标志为1且有效载荷为零字节的PUBLISH报文会被服务端当作正常消息处理,它会被发送给订阅主题匹配的客户端。此外,同一个主题下任何现存的保留消息必须被移除,因此这个主题之后的任何订阅者都不会收到一个保留消息

        如果客户端发给服务端的PUBLISH报文的保留标志位0,服务端不能存储这个消息也不能移除或替换任何现存的保留消息

    8.剩余长度 Remaining Length

        剩余长度(Remaining Length)表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数

        剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码。更大的值按下面的方式处理。低7位有效位用于编码数据,最高有效位用于指示是否有更多的字节,且按照大端方式进行编码。因此每个字节可以编码128个数值和一个延续位(continuation bit)。剩余长度字段最大4个字节

    9.可变报头 Variable header

        某些MQTT控制报文包含一个可变报头部分。它在固定报头和负载之间。可变报头的内容根据报文类型的不同而不同。可变报头的报文标识符(Packet Identifier)字段存在于多个类型的报文里

        很多控制报文的可变报头部分包含一个两字节的报文标识符字段。这些报文是PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSRIBE,UNSUBACK

    10.有效载荷 Payload

        某些MQTT控制报文在报文的最后部分包含一个有效荷载

    11.MQTT的订阅和发布模型

        客户端知道服务上有很多个主题。就好比如说有很多消息的分类一样子。有社会新闻、体育讲坛等。那么客户端只要找到自己感兴趣的进行订阅就可以了。一个客户端可以向服务器订阅多个主题。

        而所谓的发布就是客户端对不同的主题进行发布信息。即好比如新闻的发布者一样子。这个时候只要订阅这个主题的客户端就可以接收到来自服务端的新闻。我们的手机常常会接收到一些推送的信息。事实上有很多App应用都是用MQTT协议来进行的。所以不难看出服务端主要是负责客户端和客户端的之间信息的传输和信息管理。

    12.主题名和主题过滤器 Topic Names and Topic Filters

        主题通配符TopIc wildcards

        主题层级(topic level)分隔符用于将结构化引入主题名。如果存在分隔符,它将主题名分隔为多个主题层级topic level

        订阅的主题过滤器可以包含特殊的通配符,允许你一次订阅多个主题

        主题过滤器中可以使用通配符,但是主题名不能使用通配符

            主题层级分隔符:斜杠(‘/’ U+002F)用于分割主题的每个层级,为主题名提供一个分层结构

            多层通配符:数字标志(‘#’ U+0023)是用于匹配主题中任意层级的通配符

            单层通配符:加号(‘+’ U+002B)是只能用于单个主题层级匹配的通配符

            以$字符开头的主题:服务端不能将$字符开通的主题名匹配通配符(#或+)开头的主题过滤器

    13.主题语义和用法Topic semantic and usage

        主题名和主题过滤器必须符合下列规则:

            所有的主题名和主题过滤器必须至少包含一个字符

            主题名和主题过滤器是区分大小写的

            主题名和主题过滤器可以包含空格

            主题名或主题过滤器以前置或后置斜杠“/”区分

            只包含斜杠“/”的主题名或主题过滤器是合法的

            主题名和主题过滤器不能包含空字符(Unicode U+0000)【Unicode】

            主题名和主题过滤器是UTF-8编码字符串,它们不能超过65535字节

三、MQTT协议的报文示例

    1.MQTT控制报文消息类型

        MQTT控制报文一共14种,按照功能分为3类:连接类,发布类,订阅类

image.png

    2.连接类控制报文消息

        订阅与保活工作流程

            订阅

                mqtt Client

                        mqtt Server

                CONNECT

                CONNACK

                SUBSCRIBE

                SUBACK 订阅完成

                PUBLISH

            保活

                mqtt Client

                        mqtt Server

                PINGREQ

                PINGRESP

            CONNECT-连接服务端

                客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CONNECT报文

                在一个网络连接上,客户端只能发送一次CONNECT报文。服务端必须将客户端发送的第二个CONNECT报文当作协议违规处理并断开客户端

                有效载荷包含一个或多个编码的字段。包括客户端的唯一标识符,Will主题,Will消息,用户名和密码

                服务端发送CONNACK报文响应从客户端收到的CONNECT报文。服务端发送给客户端的第一个报文必须是CONNACK

            CONNACK-确认连接请求

                服务端发送CONNACK报文响应从客户端收到的CONNECT报文。服务端发送给客户端的第一个报文必须是CONNACK

                如果客户端在合理的时间内没有收到服务端的CONNACK报文,客户端应该关闭网络连接。合理的时间取决于应用的类型和通信基础设施

            CONNACK-确认连接请求 可变报头 Variable header

            PINGREQ-心跳请求

                客户端发送PINGREQ报文给服务端。用于:

                    在没有任何其它控制报文从客户端发给服务时,告知服务端客户端还活着

                    请求服务端发送响应确认还活着。

                    使用网络以确认网络连接没有断开。

            PINGRESP-心跳响应

                服务端发送PINGRESP报文响应客户端的PINGREQ报文。表示服务端还活着。

                保持连接(Keep Alive)处理中用到这个报文

            DISCONNECT-断开连接

                DISCONNECT报文是客户端发给服务端的最后一个控制报文。表示客户端正常断开连接

                服务端必须验证所有的保留位都被设置为0,如果它们不为0必须断开连接

    3.订阅类控制报文消息

            SUBSCRIBE-订阅主题

                客户端向服务端发送SUBSCRIBE报文用于创建一个或多个订阅。每个订阅注册客户端关系的一个或多个主题。为了将应用消息转发给与那些订阅匹配的主题,服务端发送PUBLISH报文给客户端。SUBSCRIBE报文也(为每个订阅)指定了最大的QoS等级,服务端根据这个发送应用消息给客户端

            SUBSCRIBE-订阅主题 有效载荷格式

                SUBSCRIBE报文的有效载荷包含了一个主题过滤器列表,它们表示客户端想要订阅的主题

            SUBACK-订阅确认

                服务端发送SUBACK报文给客户端,用于确认它已收到并且正在处理SUBSCRIBE报文

                SUBACK报文包含一个返回码清单,它们指定了SUBSCRIBE请求的每个订阅被授予的最大QoS等级

            SUBACK-订阅确认 有效载荷格式

                有效载荷包含了一个返回码清单。每个返回码对应等待确认的SUBSCRIBE报文中的一个主题过滤器

                允许的返回码值

                    0x00-最大QoS 0

                    0x01-成功-最大QoS 1

                    0x02-成功-最大QoS 2

                    0x80-Failure失败

            UNSUBSCRIBE-取消订阅

                客户端UNSUBSCRIBE报文给服务端,用于取消订阅主题

            UNSUBSCRIBE-取消订阅 有效载荷格式

                UNSUBSCRIBE报文的有效载荷包含客户端想要订阅的主题过滤器列表

            UNSUBACK-取消订阅确认

                服务端发送UNSUBACK报文给客户端用于确认收到UNSUBSVRIBE报文

4.发布类控制报文消息

            三种不同质量等级的消息分发流程

            QoS 0

                mqtt Client

                PUBLISH

                mqtt Server

            QoS 1

                mqtt Client             

                mqtt Server

                PUBLISH

                PUBACK

            QoS 2

                mqtt Client              

                mqtt Server

                PUBLISH

                PUBREC

                PUBREL

                PUBCOMP  

            QoS 0 :最多分发一次 业务流程

                消息的分发依赖于底层网络的能力。接受者不会发送响应,发送者也不会重试。消息可能送达一次也可能根本没送达

                PUBLISH-发布消息

                    PUBLISH控制报文是指客户端向服务端或者服务端向客户端传输一个应用消息

                PUBLISH-发布消息 可变报头 Variable header

                    PUBLISH报文应该包含主题名,当QoS>0时需要包含报文标识符

            QoS1:至少分发一次业务流程

                服务质量确保消息至少送达一次。QoS1的PUBLISH报文的可变报头中包含一个报文标识符,需要PUBACK报文确认

                PUBACK-发布确认

                    PUBACK报文是对QoS 1等级的PUBLISH报文的响应

            QoS2:仅分发一次 业务流程

                这是最高等级的服务质量,消息丢失和重复都是不可接受的。使用这个服务质量等级会有额外的开销。

                QoS 2的消息可变报头中的报文标识符。

                QoS 2的PUBLISH报文的接收者使用一个两步确认过程来确认收到

                发送者动作                                    

                    控制报文    

                    接收者动作

                存储消息

                发送PUBLISH报文,QoS=2,DUP=0,带报文标识符

                    方法A:存储消息,或方法B:存储报文标识符,然后开始向前分发这个应用消息

                发送PUBREC报文,带报文标识符

                丢弃消息,存储PUBREC中的报文标识符

                发送PUBREL报文,带报文标识符

                    方法A:开始向前分发应用消息然后丢弃消息或方法B:丢弃报文标识符

                发送PUBCOMP报文,带报文标识符

                丢弃已保存的状态

                PUBREC-发布收到(QoS 2,第1步)

                    PUBREC报文是对QoS等级2的PUBLISH报文的响应。它是QoS2等级协议交换的第二个报文

                PUBREL-发布释放(QoS2,第2步)

                    PUBREL报文是对PUBREC报文的响应。它是QoS 2等级协议交换的第三个报文

                PUBREL-发布完成(QoS2,第3步)

                    PUBCOMP报文是对PUBREL报文的响应。它是QoS 2等级协议交换的第四个也是最后一个报文

四、MQTT的应用

    1.MQTT业务方式

        点对点模式

        广播模式

        聚合模式

        扇出模式

    2.MQTT应用场景举例

        移动应用程序之间发送消息。移动应用使用MQTT库,使用MQTT来发送和接收消息。消息通过MQTT消息传递服务器进行交换。MQTT客户机和服务器可应对为移动应用程序可靠地传递消息所带来的复杂性,并且将网络管理成本保持在较低水平。

        MQTT还用于遥测,以接收来自传感器的数据并对传感器进行远程控制。对于移动设备和传感器,MQTT通过可靠的传送提供高度可扩展的发布/预定协议。。要发送和接收MQTT消息,需要将MQTT客户机库添加到应用程序。MQTT客户机库使用MQTT协议将移动设备和传感器的应用程序连接到MQTT服务器。

    3.MQTT应用场景

    4.智慧家庭场景网关到平台建链、订阅Topic流程

        网关到IoT平台获取deviceId,secret,MQTT Client Id

        网关向Rabbitmq发起建立链接请求

        在1883端口监听的MQTT插件转发authConnect请求

        MQTT插件收到authConnect鉴权Allow的响应后,将MQTT client建链请求发送RabbitMq内核,然后MQTT client和RabbitMq建立建链成功

        网关发起订阅topic请求

        Cig调用IoCM注册路由接口


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200