赞
踩
看文档的时候想起以前整理过一篇关于MQTT协议的扫盲内容,分享一下。
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议 上,由IBM在1999年发布。
MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
相较于HTTP
在传统互联网应用中,HTTP被广泛应用。通常情况下,客户端的设备配置、网络环境都比较可控,另外请求通常会基于各种业务传递大量的数据。
但是对于物联网来说,网络不稳定、设备能力不够,是重点考虑的因素。再者物联网传输的消息大小远小于传统互联网的业务数据,如果每次发送数据都来一次连接/断开TCP,发送的数据越多,数据总通信量也就越大。
再有就是在灵活性上HTTP的请求-响应模式也不如MQTT的发布/订阅模式。必须由设备主动向服务器发送数据,而服务器难以主动向设备推送数据。对于单单的数据采集等场景还勉强适用,但是对于频繁的操控场景,只能推过设备定期主动拉取的的方式,实现成本和实时性都大打折扣。
由于物联网的环境是非常特别的,所以MQTT遵循以下设计原则:
发明人当时正在开发一个利用卫星通讯监控输油管道的项目。为了实现这个项目要求,他们需要开发一种用于嵌入式设备的通讯协议。 从诞生之初就是专为低带宽、高延迟或不可靠的网络而设计的。虽然历经几十年的更新和变化,以上这些特点仍然是MQTT协议的核心特点。但是与最初不同的是,MQTT协议已经从嵌入式系统应用拓展到开放的物联网(IoT)领域。
版本
目前MQTT主流版本有两个,分别是MQTT3.1.1
和MQTT5
。MQTT3.1.1
是在2014年10月发布的,而MQTT5
是在2019年3月发布的。 MQTT5是在 MQTT3.1.1
的基础上进行了升级,添加了更多的功能、完善 MQTT 协议。因此MQTT5是完全兼容MQTT3.1.1
的。
MQTT 并不是消息队列,尽管两者的很多行为和特性非常接近,比如都采用发布订阅模式等,但是他们面向的场景有着显著的不同。
在实际的场景中,两者往往被结合起来使用,譬如先由 MQTT Broker 接收物联网设备上传的数据,然后通过消息队列MQ将这些数据转发到具体应用进行处理。
在车联网中有一个重要角色:TSP(Telematics Service Provider)汽车远程服务提供商。TSP 上接汽车、车载设备制造商、网络运营商,下接内容提供商。
既然身处核心地位,自然少不了与其他环节的各种交互,比如说云平台与车机端的消息接入。
而 MQTT 是基于发布/订阅模式的物联网通信协议,具有简单易实现、支持 QoS、报文小等特点,在车联网场景中,MQTT 能够胜任海量车机系统灵活、快速、安全地接入,并保证复杂网络环境下消息实时性、可靠性。主要优势:
实现MQTT协议需要客户端和服务器端通讯完成。在通讯过程中,MQTT协议中有三种身份 :发布者(Publish)
、代理(Broker)(服务器)
、订阅者(Subscribe)
。
其中,消息的发布者和订阅者都是客户端,消息代理是服务器。
客户端
MQTT客户端可以向服务端发布信息,也可以从服务端收取信息。
我们把客户端发送信息的行为称为发布信息。而客户端要想从服务端收取信息,则首先要向服务端订阅信息。订阅信息这一操作很像我们在视频网站订阅某一类型电视剧。当这部电视剧上新后,视频网站会向订阅了该剧的用户发送信息,告诉他们有新剧上线了。
服务器
MQTT 服务端通常是一台服务器,也称为“消息代理”(Broker)
。位于消息发布者和订阅者之间,它是MQTT信息传输的枢纽,负责将MQTT客户端发送来的信息传递给MQTT客户端。
MQTT 服务端还负责管理 MQTT 客户端。确保客户端之间的通讯顺畅,保证 MQTT 消息得以正确接收和准确投递。
刚刚我们在讲解 MQTT 客户端订阅信息时,使用了用户在视频网站订阅电视剧这个例子。在 MQTT 通讯中,客户端所订阅的肯定不是一部部电视剧,而是一个个主题。MQTT 服务端在管理 MQTT 信息通讯时,就是使用主题来控制的。
再来举个例子:
在以上图示中一共有三个MQTT客户端: 它们分别是汽车,手机和电脑。 假设我们需要利用手机和电脑获取汽车的速度, 那么我们首先要利用电脑和手机向MQTT服务器订阅主题“汽车速度”。 接下来,当汽车客户端向服务端的“汽车速度”主题发布 信息后,服务端就会首先检查以下都有哪些客户端 订阅了“汽车速度”这一主题的信息。 当它发现订阅了该主题的客户端有一个手机和一个电脑, 于是服务端就会将刚刚收到的“汽车速度”信息转发给订阅了 该主题的手机和电脑客户端。 在以上实例中,汽车是“汽车速度”主题的发布者, 而手机和电脑则是该主题的订阅者。
另外,消息发布者同时也可以是订阅者 ,看图:
上图中的所有客户端都是围绕“空调温度”这一主题
进行通讯的。
对于“空调温度”这一主题,手机和电脑客户端成为
了MQTT信息的发布者,而汽车则成为了MQTT信息的
订阅者(接收者)。
所以,针对不同的主题,MQTT客户端可以切换
自己的角色。它们可能对主题A来说是信息发布者,
但是对于主题B就成了信息订阅者。
从上述列子可以看出,MQTT通讯的核心枢纽是MQTT服务端。有了服务端对MQTT信息的接收、储存、处理和发送,客户端在发布和订阅信息时,可以相互独立,且在空间上可以分离,时间上可以异步。
MQTT客户端是一个个独立的个体。它们无需了解彼此的存在,依然可以实现信息交流。
比如以上实例中汽车客户端在发布“汽车速度”信息时,汽车客户端本身可以完全不知道有多少个MQTT客户端订阅了“汽车速度”这一主题。而订阅了“汽车速度”主题的手机和电脑客户端也完全不知道彼此的存在。
大家只要订阅了“汽车速度”主题,MQTT服务端就会在每次收到新信息时,将信息发送给订阅了“汽车速度”主题的客户端。
MQTT客户端在通讯时必要条件是连接到了同一个MQTT通讯网络。这个网络可以是互联网或者局域网。只要客户端联网,无论在哪里,都可以实现彼此间的通讯交流。
MQTT客户端在发送和接收信息时无需同步。这一特点对物联网设备尤为重要。有时物联网设备会发生意外离线的情况。比如当我们的汽车在行驶过程中,可能会突然进入隧道,这时汽车可能会断开与MQTT服务端的连接。
假设在此时我们的手机客户端向汽车客户端所订阅的“空调温度”主题发布了信息,而汽车恰恰不在线。这时,MQTT服务端可以将“空调温度”主题的新信息保存,待汽车再次上线后,服务端再将“空调温度”信息推送给汽车。
从客户端向服务端发起 MQTT 连接请求开始,到连接中断,直到会话过期为止的消息收发序列称之为会话。
因此,会话可能仅持续一个网络连接,如果客户端能在会话过期之前重新建立了连接的话,会话也可能跨越多个网络连接存在。
会话状态的使用
如果客户端因为网络波动等原因导致连接短暂中断,但在会话过期前重新与服务端建立了连接,那么就可以沿用上次连接建立的订阅关系,不需要重新订阅一遍。
在低带宽、不稳定的网络场景下,网络中断可能会发生得很频繁,保存会话状态的方式避免了每次连接都需要重新订阅,降低了重连时客户端和服务端的资源消耗。
服务端在客户端脱机期间为其保留未完成确认的以及后续到达的消息,客户端重新连接时再一并转发,既可以避免消息丢失,也能够降低某些场景下用户对网络变化的感知度。
一个物联网系统中有些信息非常重要,我们需要确保这类重要信息可以准确无误的发送和接收。如果有些信息在传输中丢失但是不会影响系统的运行,则相对不那么重要。
MQTT服务质量(Quality of Service 缩写 QoS)正是用于告知物联网系统,哪些信息是重要信息需要准确无误的传输,而哪些信息不那么重要,即使丢失也没有问题。
MQTT 设计了 3 个 QoS 等级:
QoS 0
:消息最多发 1 次,占用的网络资源最低。发送端一旦发送完消息后,就完成任务了。发送端不会检查发出的消息能否被正确接收到。
在网络环境稳定的情况下,信息传输一般是不会出现问题的。但是在环境不稳定的情况下,可能会在传输过程中出现MQTT消息丢失的情况,所以适用于传输重要性较低的信息。
QoS 1
:消息最少发 1 次,但是有可能出现接收端反复接收同一消息的情况。发送端在消息发送完成后,会检查接收端是否已经成功接收到了消息。
发送端将消息发送给接收端后,会等待接收端的确认。接收端成功接收消息后,会发送一条确认报文PUBACK
给发送端。如果发送端收到了这条PUBACK
确认报文,那么它就知道消息已经成功接收。
假如过了一段时间后,发送端没有收到PUBACK
报文,那么发送端会再次发送消息,然后再次等待接收端的PUBACK确认报文。因此,发送端在没有收到接收端的PUBACK
确认报文以前,会重复发送同一条消息。
当发送端重复发送一条消息时,PUBLISH报文中的dupFlag
会被设置为True
,为了告诉接收端,此消息为重复发送的消息。
MQTT协议可以确保接收端只接收一次消息。但是收发过程相对更加复杂,发送端需要接收端进行两次消息确认。因此,QoS 2
最安全的服务级别,也是最慢的服务级别。此类服务等级适用于重要消息传输。
Tips:由于QoS1和QoS2都能确保客户端接收到消息,但是QoS1所占用的资源较QoS2占用资源更小。因此建议使用QoS1来实现网络资源较为珍贵的环境下传输重要信息。
服务质量降级
对于发布和订阅消息的客户端,服务端会主动采用较低级别的QoS来实现消息传输。
场景1:
假如客户端A
发布到主题1
的消息是采用QoS = 2
,然而客户端B
订阅主题1
采用QoS = 1
。
在这种情况下,服务端会使用较低级别来提供服务。
虽然A
发送到主题1
的消息采用QoS为2
,但是由于B
在订阅主题1
时采用的QoS为1
,所以服务端
发送主题1
的消息给B
时,采用的QoS为1
。
场景2:
假如客户端A
发布主题1
消息时使用QoS为0
,而客户端B
订阅主题1
消息时使用`QoS为1。
虽然客户端B
订阅主题1
消息时QoS为1
,但是由于客户端A
发送主题1
消息时QoS为0
,所以服务端
发送消息给B
的QoS为0
。
有个这样的场景:
一套智能家居物联网系统,有一个检测室温的
MQTT客户端,每整点时把当前室温
向MQTT服务端发布。
系统中还有另一个客户端用于显示温度信息,
客户端一启动就会订阅室温主题。
正常情况下:假如上午7:00,室温检测客户端
将最新的室温消息发布到了服务端,那么订阅了
室温消息的显示客户端也就马上获取到室温消息
并且显示在屏幕上。
但是,7点10分的时候,显示客户端的插头被
碰掉了,手动恢复通电后,客户端启动后会立刻
订阅室温主题。
问题来了,室温客户端每到整点才发布一次温度信息。上一次发布时间是7:00
,下一次发布时间是8:00
。所以,尽管显示客户端订阅了室温主题,它还要等到8:00
钟才能收到最新室温消息。在8:00
前的几十分钟里,显示客户端无法获知当前室温信息。
为了避免以上情况出现,可以让室温测量客户端在每次向室温主题发布消息时都使用保留消息
这一模式将温度信息发布到服务端。这样无论显示客户端在任何时间订阅室温主题,都会马上收到该主题中的保留消息
。
客户端在没有向服务端发送信息时,可以定时向服务端发送一条消息。这条用于心跳机制的消息也被称作心跳请求(PINGREQ)。
心跳请求的作用正是**用于告知服务端,当前客户端依然在线 **。
服务端在收到客户端的心跳请求后,会回复一条消息。这条回复消息被称作心跳响应(PINGRESP)。
心跳时间间隔
我们在开发客户端时,可以对其进行设置。
设置好心跳时间间隔后,客户端就知道多久要发送一条心跳请求给服务端。当客户端连接服务端时,会将心跳时间间隔信息放入CONNECT
报文中的keepAlive
。
图中keepAlive
数值为60
。这就意味着,客户端的心跳间隔时间是60秒
。
客户端掉线
另外,在实际运行中,如果服务端没有在1.5倍心跳时间间隔内
收到客户端发布消息(PUBLISH)或发来心跳请求(PINGREQ),那么服务端就会认为这个客户端已经掉线
。
小结一下,心跳机制可以让服务端随时掌握客户端连接情况。当客户端“心跳”正常时,服务端即知道客户端仍然在线(活着)
。当心跳一旦停止,服务端就会发现该客户端已经断线(死亡)
。
为了让客户端可以更好的发挥作用,便于服务端管理,MQTT 协议允许客户端在“活着”的时候就写好遗嘱,这样一旦客户端意外断线
,服务端就可以将客户端的遗嘱公之于众。
注意:客户端的遗嘱只在意外断线时才会发布,如果客户端正常的断开了与服务端的连接,这个遗嘱机制是不会启动的,服务端也不会将客户端的遗嘱公布。
意外断线包括但不限于:
整体由3个部分组成:
固定报头 Fixed header
:存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识;可变报头 Variable header
:存在于部分MQTT数据包中,数据包类型决定了可变头是否整体 MQTT 的消息格式如下图所示:
数据包里目前不进行展开,后面进一步需要接触后,另起篇幅介绍。
从本章开始,在没有特殊说明的情况下,文章中的MQTT版本均为 3.1.1。
MQTT 协议是物联网中常见的协议之一,“轻量级物联网消息推送协议”,MQTT同HTTP属于第七层(应用层)。
对于网络分层还不太熟悉的朋友请点击:《网络OSI七层模型及各层作用 与 TCP/IP》
参考:《物联网网关中MQTT和Modbus之间有何区别 》、《MQTT 入门介绍》
文档资料:《MQTT协议中文版资料》、《MQTT协议英文版资料》
在物联网中,开源和开放标准是基本的要素。MQTT 的发展历史大致如下:
MQTT
是机器对机器(M2M
)/物联网(IoT
)连接协议。它被设计为一个极其轻量级的发布/订阅
消息传输协议。对于需要较小代码占用空间和/或网络带宽非常宝贵的远程连接非常有用,是专为受限设备和低带宽、高延迟或不可靠的网络而设计。这些原则也使该协议成为新兴的“机器到机器”(M2M
)或物联网(IoT
)世界的连接设备,以及带宽和电池功率非常高的移动应用的理想选择。例如,它已被用于通过卫星链路与代理通信的传感器、与医疗服务提供者的拨号连接,以及一系列家庭自动化和小型设备场景。它也是移动应用的理想选择,因为它体积小,功耗低,数据包最小,并且可以有效地将信息分配给一个或多个接收器。
为什么不选择其他众多网络协议 ?
大多数开发人员已经熟悉 HTTP Web 服务。那么为什么不让 IoT 设备连接到 Web 服务?设备可采用 HTTP 请求的形式发送其数据,并采用 HTTP 响应的形式从系统接收更新。这种请求和响应模式存在一些严重的局限性:
- HTTP 是一种同步协议。客户端需要等待服务器响应。Web 浏览器具有这样的要求,但它的代价是牺牲了可伸缩性。在 IoT 领域,大量设备以及很可能不可靠或高延迟的网络使得同步通信成为问题。异步消息协议更适合 IoT 应用程序。传感器发送读数,让网络确定将其传送到目标设备和服务的最佳路线和时间。
- HTTP 是单向的。客户端必须发起连接。在 IoT 应用程序中,设备或传感器通常是客户端,这意味着它们无法被动地接收来自网络的命令。
HTTP 是一种 1-1 协议。客户端发出请求,服务器进行响应。将消息传送到网络上的所有设备上,不但很困难,而且成本很高,而这是 IoT 应用程序中的一种常见使用情况。
- HTTP 是一种有许多标头和规则的重量级协议。它不适合受限的网络。
出于上述原因,大部分高性能、可扩展的系统都使用异步消息总线来进行内部数据交换,而不使用 Web 服务。事实上,企业中间件系统中使用的最流行的消息协议被称为 AMQP(高级消息排队协议)。但是,在高性能环境中,计算能力和网络延迟通常不是问题。AMQP 致力于在企业应用程序中实现可靠性和互操作性。它拥有庞大的特性集,但不适合资源受限的 IoT 应用程序。
除了 AMQP 之外,还有其他流行的消息协议。例如,XMPP(Extensible Messaging and Presence Protocol,可扩展消息和状态协议)是一种对等即时消息 (IM) 协议。它高度依赖于支持 IM 用例的特性,比如存在状态和介质连接。与 MQTT 相比,它在设备和网络上需要的资源都要多得多。
那么,MQTT 为什么如此轻量且灵活?因为MQTT 协议的一个关键特性是发布和订阅模型。与所有消息协议一样,它将数据的发布者与使用者分离。
我们先来看看一个典型的MQTT网络拓扑结构长什么样子,再来介绍有关概念。
实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。应用消息通过MQTT传输时,它们有关联的服务质量(QoS)和主题(Topic)。
完整流程
客户端 Client
使用MQTT的程序或设备。客户端总是通过网络连接到服务端。它可以
服务端 Server
一个程序或设备,作为发送消息的客户端和请求订阅的客户端之间的中介。服务端
订阅 Subscription
订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。
主题名 Topic Name
附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本给每一个匹配的客户端订阅。
主题名称(Topic name)用来标识已发布消息的信息的渠道。订阅者用它来确定接收到所关心的信息。它是一个分层的结构,用斜线“/”作为分隔符(这个有点类似于restful风格)。
主题过滤器 Topic Filter
订阅中包含的一个表达式,用于表示相关的一个或多个主题。主题过滤器可以使用通配符。
主题还可以通过通配符进行过滤。其中,+可以过滤一个层级,而#只能出现在主题最后表示过滤任意级别的层级。
值得注意的是MQTT允许使用通配符订阅主题,但是并不允许使用通配符广播。
举个例子:
building-b/floor-5:代表B楼5层的设备。
+/floor-5:代表任何一个楼的5层的设备。
building-b/#:代表B楼所有的设备。
会话 Session
客户端和服务端之间的状态交互。一些会话持续时长与网络连接一样,另一些可以在客户端和服务端的多个连续网络连接间扩展。
控制报文 MQTT Control Packet
通过网络连接发送的信息数据包。MQTT规范定义了十四种不同类型的控制报文,其中一个(PUBLISH报文)用于传输应用消息。
MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:
由于物联网的环境是非常特别的,所以MQTT遵循以下设计原则:
MQTT协议广泛应用于物联网、移动互联网、智能硬件、车联网、电力能源等领域。
一、订阅(Subscription)
订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。
二、会话(Session)
每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。
三、主题名(Topic Name)
连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。
四、主题筛选器(Topic Filter)
一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。
五、负载(Payload)
消息订阅者所具体接收的内容。
这一章是在下载 MQTT代码源码中发现,并查阅资料后进行补充的。
MQTT-SN(Sensor Networks)是MQTT协议的传感器版本,基于TCP协议的MQTT对有些传感器来说还是负载太重了,这些传感器可能只有几十个字节的内存,无法运行TCP协议。MQTT-SN对MQTT对内存受限的微处理器做了适当的优化,使之能够跑在这种处理器上。
也就是说,MQTT与MQTT-SN 之间需要转换才能够互通。转换的操作由MQTT-SN的网关完成。
原名是MQTT-S,但会引起人们的误解,因此更名成MQTT-SN:
As part of the job of applying the same or similar license terms to the MQTT-S specification as those on the MQTT specification, we are proposing a small name change. The new name would be MQTT-SN, standing for exactly the same long name, MQTT for Sensor Networks. Some people had assumed that the S in MQTT-S stood for secure, so we hope this change will avoid that confusion. – Ian Craggs
MQTT for Sensor Networks is aimed at embedded devices on non-TCP/IP networks, such as Zigbee. MQTT-SN is a publish/subscribe messaging protocol for wireless sensor networks (WSN), with the aim of extending the MQTT protocol beyond the reach of TCP/IP infrastructure for Sensor and Actuator solutions.
针对适配传感装置(缩写为SA)的特定版MQTT协议,一般运行在嵌入式电池驱动的电子元件中,传输通过基于IEEE 802.15.4规范无线低速网络构成的无线传感网络(WSN),同样具有企业级别特性具有以数据为核心的(data-centric)订阅/发布特性。
总之,针对低功耗、电池驱动、处理存储受限的设备、不支持TCP/IP协议栈网络的电子器件而定制,比如常见的ZigBee(或XBee),对所依赖的底层传输网络不可知,但只要网络支持双向数据传输和网关,都是可以支持较为上层的MQTT-SN协议传输。比如简单数据报服务,只要支持一个源端点发送数据到一个特定目的地端点,这对支持MQTT-SN协议,就足够了。广播数据报传输服务也是必须的用于网关和终端的自动发现流程。为了降低广播风暴,MQTT-SN定义了广播路径深度(广播范围或广播半径)。
尽管MQTT-SN被设计成尽可能接近于MQTT,但那些低功耗、电池驱动、资源受限的设备所在网络场景为低速带宽、高连接失败、物理层数据包上线为128字节。文档提出了以下不同点:
在MQTT-SN架构图中,存在三种组件:
MQTT-SN网关传输方式,下面的图片一目了然。透明网关,会为每一个客户端都建立一个TCP连接到MQTT服务器的通道,这样会较为耗费网关网络资源,但模型简单
网关需要抉择哪些消息需要和远程的MQTT Server进行交互,比如只选择客户端发送的PUBLISH、SUBSCRIBLE消息等。
转自:https://mp.weixin.qq.com/s?__biz=MzI0OTQwNDQxMw==&mid=2247484577&idx=1&sn=6ae197287cd0cbd26c0cc8873e02bd28&chksm=e9934a33dee4c325f9f2b77c9bca87e7785787d59a4c182ffe48d4e7d2a240130f511c9c6108&scene=27
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。