【物联网】一篇带你读懂什么是MQTT

概述

MQTT即Message Queuing Telemetry Transport,是一个客户端/服务端架构发布(publish)/订阅(subscribe) 范式的消息传输协议,它工作在TCP/IP协议族上 ,是为硬件性能低下的远程设备以及网络状况糟糕的情况下( 低带宽、高延迟、不可靠 )而设计的发布订阅型消息队列

发展史

MQTT协议最早是1999年由Andy Stanford Clark 和 Arlen Nipper 共同创建的,当时他们正在开发一个利用卫星监控输油管道的项目(即需要通过在石油管道上的传感器向卫星🛰️传输状态数据),他们需要开发一种嵌入式设备的通信协议,该协议需要满足数据传输的服务质量可控并且传输内容不可预知、设备连接状态可知、占用带宽小并且易于实现,因此相比HTTP协议,MQTT协议的电池损耗与占用带宽都更低,因此逐渐从嵌入式系统应用拓展到开放的物联网领域,成为当前世界上最受欢迎的物联网协议,后来在OASIS(结构化信息标准促进组织,Organization for the Advancement of Structured of Structured Information Standards)推动下于2019年公布了最新的v5.0版本。

发布/订阅模式

由于物联网网络不稳定的特点,如果信号不好就很容易发生数据丢失的现象,于是就增加了MQTT服务端,通讯时会先把信息发送到"中转站"(MQTT服务器会进行"必要"的保存),以提高服务的稳定性,同时MQTT服务器还会通过"主题"来判断这些信息需要分发给哪些客户端。

我们来看一个例子,汽车可以作为发布者通向MQTT服务器发送主题为"Speed"的汽车行驶速度的信息,用户的手机和电脑可以作为接收者订阅"Speed"的主题,这样MQTT服务器就会在接收到"Speed"主题的信息后,将它分发给定于了这个主题的客户端(即下图中的手机和电脑)

当然,上图中作为发布者的汽车也可以作为接收者,而刚刚作为接收者的手机和电脑也可以成为发布者(如下图可以通过手机和电脑控制车内温度)

发布/订阅模式Publish/Subscribe)实际上是一种时间异步 +空间分离 的模式,即客户端在发布和订阅信息时,可以相互独立,有了MQTT服务器对信息进行接受、存储、处理、分发,消息发布方无需与消息订阅方进行直接通信,即发送消息的发布者 (Publisher)与接收消息的订阅者(Subscribers)是分离的,甚至彼此之间都不知道对方的存在(发布者并不知道有多少个订阅者,订阅者也不知道出了自己是否还有别的订阅者)。

如何连接MQTT服务端

如果一个客户端想要进行信息的发布/订阅,首先需要连接上MQTT服务端,那么如何进行连接呢?

大体上分为两个步骤:

客户端项服务端发送🔗连接请求------"CONNECT"

首先客户端会先向服务端发送连接请求(其实就是一个数据包,官方名称"CONNECT")

这个数据包大概长这样

  • clientId:可以理解为客户端的名字,服务端就是通过这个名字来管理不同的客户端的,因此对于同一个服务端clientId不可重复
  • cleanSession:确认当前客户端是否是一个重要的客户端(注意⚠️false表示"是"),如果当前客户端是一个重要的客户端那么在没收到客户端收到消息的确认回复就会把该信息保存起来(不清理),后面会继续进行发送,直到收到客户端的确认信息(一般与参数Qos配合使用)
  • username 用户名(可选)
  • password 密码(可选)
  • lastWillTopic 遗嘱主题(可选)
  • lastWillQos 遗嘱等级(可选)
  • lastWillMessage 遗嘱信息(可选)
  • lastWillRetain 是否有遗嘱(可选)
  • keepAlive:心跳时间间隔,为了确保设备连接状态可知,通过心跳机制确认客户端是否还在线,超过keepAlive所设置的时间未接收到客户端的心跳包,则视为该客户端已下线

服务端向客户端发送🔗连接确认------"CONNACK"

MQTT服务端收到客户端的"CONNECT"数据包后,会向该客户端发送确认连接(其实也是一个数据包,官方名称"CONNACK")

这个数据包长这样:

  • sessionPresenttrue表示服务端之前还有没发送的信息

  • returnCode:返回码

    • 0:成功连接🔗
    • 1:连接被服务端拒绝❌(服务端不支持客户端的MQTT版本)
    • 2:连接被服务端拒绝❌(服务端不支持客户端的标识符编码)
    • 3:连接被服务端拒绝❌(服务端不可用)
    • 4:连接被服务端拒绝❌(用户名/密码无效)
    • 5:连接被服务端拒绝❌(客户端未被授权到此服务端)

我们使用MQTTX来测试下(软件可通过官方渠道进行下载⏬,目前无收费情况),按照下图中的编号顺序进行设置

4中的Host建议先选择公共MQTT服务器进行测试,比如Mosquitto (官网地址:www.mosquitto.org),它的MQTT服务器地址是:test.mosquitto.org,TCP 端口:1883,TCP/TLS 端口:8883,WebSockets 端口:8080,Websocket/TLS 端口:8081

都设置完成后,点击右上角的连接,弹出"Connected"即表示连接成功

如何发布/订阅/取消订阅

发布

其实也就是在上面连接服务端后,再向服务端发一个发布数据包------"PUBLISH"

这个包大概长这样

  • packetId:用于服务端管理数据包
  • topicName:信息(payload)是向哪个主题发布的
  • qos:服务质量
  • retailFlag:保留标志,true表示会保留信息,即如果有新的客户端订阅了这个主题就会立刻把这些保留的信息发送给这个新订阅的客户端(新订阅的客户端不用等到新信息发送时才能收到第一条信息)
  • payload:发布的具体信息
  • dupFlag:重发标志

订阅

以此类推~不过订阅这里需要两个步骤,即客户端订阅+服务端确认

订阅是在连接服务端后,向服务端发一个订阅数据包------"SUBSCRIBE",该报文包含有一系列(一个或多个)订阅主题名,也就是说,一个SUBSCRIBE报文可以用于订阅一个或者多个主题。

在以上PUBLISH报文讲解中,我们曾经提到过QoS(服务质量等级)这一概念。同样的,客户端在订阅主题时也可以明确QoS。服务端会根据SUBSCRIBE中的QoS来提供相应的服务保证。

另外每一个SUBSCRIBE报文还包含有"报文标识符" 。报文标识符可用于对MQTT报文进行标识。不同的MQTT报文所拥有的标识符不同。MQTT设备可以通过该标识符对MQTT报文进行甄别和管理。

接着服务端接收到客户端的订阅报文后,会向客户端发送一个订阅确认数据包------"SUBACK"

SUBACK报文包含有"订阅返回码" 和"报文标识符" 这两个信息。

  • returnCode -- 订阅返回码,以告知客户端是否成功订阅了主题(针对不同的主题订阅QoS,服务端的返回码会有所不同

    • 0:QoS为0时的订阅成功
    • 1:QoS为1时的订阅成功
    • 2:QoS为2时的订阅成功
    • 128:订阅失败
  • 报文标识符: MQTT设备通过标识符对报文进行管理

取消订阅

再类推~取消订阅也是需要两个步骤,即客户端取消+服务端确认

当不需要再订阅某个/某些主题时,向服务端发一个取消订阅的数据包------"UNSUBSCRIBE"

该报文大概长这样

包含有一系列(一个或多个)需要取消的订阅主题名,一个SUBSCRIBE报文可以包含有单个或者多个订阅主题名,也就是说,一个SUBSCRIBE报文可以用于订阅一个或者多个主题。另外,UNSUBSCRIBE报文也包含"报文标识符",MQTT设备可以通过该标识符对报文进行管理。当服务端接收到UNSUBSCRIBE报文后,会向客户端发送取消订阅确认报文 -- UNSUBACK报文。该报文含有客户端所发送的"取消订阅报文标识符"。

相关推荐
GZ_TOGOGO14 分钟前
【2024最新】华为HCIE认证考试流程
大数据·人工智能·网络协议·网络安全·华为
三金121381 小时前
SpringIoC容器的初识
网络·网络协议·rpc
SizeTheMoment3 小时前
初识HTTP协议
网络·网络协议·http
芯橦4 小时前
【瑞昱RTL8763E】音频
单片机·嵌入式硬件·mcu·物联网·音视频·visual studio code·智能手表
程序员-珍6 小时前
虚拟机ip突然看不了了
linux·网络·网络协议·tcp/ip·centos
Evand J7 小时前
物联网智能设备:未来生活的变革者
人工智能·物联网·智能手机·智能家居·智能手表
魏大橙8 小时前
linux RCE本地/公网测试
网络·网络协议·udp
鄃鳕9 小时前
HTTP【网络】
网络·网络协议·http
秋夫人13 小时前
http cache-control
网络·网络协议·http
limengshi13839217 小时前
通信工程学习:什么是RIP路由信息协议
网络·网络协议·学习·智能路由器·信息与通信