<物联网>MQTT协议学习笔记

MQTT Version 3.1.1

在这里插入图片描述

1.MQTT(Message Queuing Telemetry Transport)

MQTT是一个客户端服务端架构的发布/订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是受限的环境如机器与机器的通信(M2M)以及物联网环境(IOT)。

MQTT协议是一种很轻的通讯协议。与HTTP之类的协议相比,MQTT在通过网络传输数据时表现出众。另一个重要特点是易于在客户端实现。因此,MQTT成为了当今世上最受欢迎的物联网协议。

目前MQTT主流版本有2个,分别是MQTT3.1.1和MQTT5。MQTT3.1.1是在2014年10月发布的,而MQTT5的发布时间距今不久。

MQTT5是在MQTT3.1.1的基础上进行了升级。因此MQTT5是完全兼容MQTT3.1.1的。

2.MQTT基本原理

在MQTT协议通讯中,有两个最为重要的角色。它们分别是服务端客户端

2.1 MQTT服务端

MQTT服务端通常是一台服务器。它是MQTT信息传输的枢纽,负责将MQTT客户端发送来的信息传递给MQTT客户端。MQTT服务端还负责管理MQTT客户端。确保客户端之间的通讯顺畅,保证MQTT消息得以正确接受和正确投递。

2.2 MQTT客户端

MQTT客户端可以向服务端发布信息,也可以从服务端收取信息。把客户端发送信息的行为称为“发布”信息。而客户端要想从服务端收取信息,则首先要向服务端“订阅信息”。

2.3 MQTT主题

MQTT服务端在管理MQTT信息通讯时,就是使用“主题”来控制的。

2.4 MQTT发布/订阅 特性

MQTT通讯的核心枢纽是MQTT服务端。有了服务端对MQTT信息的接受、储存、处理和发送,客户端在发送和订阅消息时,可以相互独立,且在空间上可以分离时间上可以异步

3.连接MQTT服务端

MQTT客户端之间要想实现通讯,必须要通过MQTT服务端。

MQTT客户端连接服务端一共有两步。

  1. 首先MQTT客户端将会向服务端发送连接请求。该请求实际上是一个包含有请求信息的数据包。这个数据包的官方名称为CONNECT
  2. 服务端收到客户端连接请求后,会向客户端发送连接确认。同样的,该确认也是一个数据包。这个数据包官方名称为CONNACK

在这里插入图片描述
在这里插入图片描述

MQTT客户端要向连接服务端,首先要向服务端发送CONNECT报文。CONNECT报文的格式和内容需符合MQTT规范,否则服务器会拒绝客户端的连接请求。

所谓报文就是一个MQTT数据包。这个数据包中包含多个信息。

a.CONNECT-连接服务端

在这里插入图片描述

3.1 clientId-客户端ID

ClientId是MQTT客户端的标识。MQTT服务端用该标识来识别客户端。因此ClientId必须是独立唯一的。通常ClientId是由一串字符所构成的,如:client-1。

3.2 cleanSession-清除会话

MQTT客户端与服务端的连接可能不是非常稳定,因此,我们要根据客户端对系统运行的重要性来区别对待。

为了保证重要的MQTT报文可以被客户端准确无误地收到,在服务端向客户端发送报文后,客户端会向服务端返回一个确认报文。如果服务端没有收到客户端返回的确认报文,那么服务端就会认为刚刚发送给客户端的报文没有被准确的送达。在这种情况下,服务端就会执行以下两个操作:
操作1:将尚未被客户端确认的报文保存起来
操作2:再次尝试向客户端发送报文,并且再次等待客户端发来确认信息。

如果cleanSession被设置为"true"。那么服务端不需要客户端确认收到报文,也不会保存任何报文。在这种情况下,即使客户端错过了服务端发来的报文,也没办法让服务端再次发送报文。

反过来,我们将cleanSession设置为"false",那么服务端就知道,后续通讯中,客户端可能会要求我保存没有收到的报文。注意,如果需要客户端保存重要报文,光设置cleanSession为false是不够的,还需要传递的MQTT信息Qos级别>0

3.3 keepAlive-心跳时间间隔

KeepAlive用于服务端实时了解客户端是否与其保持连接的情况。

b. CONNACK-确认连接请求

在这里插入图片描述

3.4 returnCode-连接返回码

当服务端收到了客户端的连接请求后,会向客户端发送returnCode(连接返回码),用以说明连接情况。如果客户端与服务端成功连接,则返回数字“0”。如果未能成功连接,连接返回码将会是一个非零的数值。

在这里插入图片描述

3.5 sessionPresent-当前会话

首先,当客户端发送的CONNECT报文中的cleanSession设置为true。在这种情况下,客户端是不需要服务端保存任何报文的。那么服务端发送的确认连接CONNACK报文中,sessionPresent肯定是false,也就是说,服务端没有保存任何报文。

当客户端发送的CONNECT报文中的cleanSession设置为false时,客户端是要求服务端保存报文的。在这种情况下,如果服务端的确保存了没有收到客户端接收确认的报文信息,那么sessionPresent为true,否则为false。

4.服务端连接操作

4.1 mqttfx安装

官网

4.2 first-MQTT连接

在这里插入图片描述
在这里插入图片描述

5.发布、订阅和取消订阅

5.1 PUBLISH-发布消息

每条发布的MQTT消息必须包含一个主题,MQTT服务器可以通过主题确定将消息转发给哪些客户端。

在这里插入图片描述

MQTT客户端发布消息时,会向服务端发送PUBLISH报文。
在这里插入图片描述

1. topicName-主题名

主题名用于识别此信息应发布到哪一个主题。

2.Qos-服务质量等级

QoS(Quality of Service)表示MQTT消息的服务质量等级。QoS有三个级别:0、1和2。QoS决定MQTT通讯有什么样的服务保证。

3.packId-报文标识符

报文标识符可用于对MQTT报文进行标识。不同的MQTT报文所拥有的标识符不同。MQTT设备可以通过该标识符对MQTT报文进行甄别和管理。请注意:报文标识符的内容与QoS级别有密不可分的关系。只有QoS级别大于0时,报文标识符才是非零数值。如果QoS等于0,报文标识符为0。

4.retainFlag-保留标志

在默认情况下,当客户端订阅了某一主题后,并不会马上接收到该主题的信息。只有在客户端订阅该主题后,服务端接收到该主题的新信息时,服务端才会将最新接收到的该主题信息推送给客户端。

但是在有些情况下,我们需要客户端在订阅了某一主题后马上接收到一条该主题的信息。这时候就需要用到保留标志这一信息。

5.Payload-有效载荷

有效載荷是我们希望通过MQTT所发送的实际内容。我们可以使用MQTT协议发送文本,图像等格式的内容。这些内容都是通过有效載荷所发送的。

6.dupFlag-重发标志

当MQTT报文的接收方没有及时确认收到报文时,发送方会重复发送MQTT报文。在重复发送MQTT报文时,发送方会将此“重发标志”设置为true。注意,重发标志只在QoS级别大于0时使用。

5.2 SUBSCRIBE–订阅主题

客户端要想订阅主题,首先要向服务端发送主题订阅请求。客户端是通过向服务端发送SUBSCRIBE报文来实现这一请求的。该报文包含有一系列“订阅主题名”。请留意,一个SUBSCRIBE报文可以包含有单个或者多个订阅主题名。也就是说,一个SUBSCRIBE报文可以用于订阅一个或者多个主题。

客户端在订阅主题时也可以明确QoS。服务端会根据SUBSCRIBE中的QoS来提供相应的服务保证。

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

5.3 SUBACK – 订阅确认

服务端接收到客户端的订阅报文后,会向客户端发送SUBACK报文确认订阅。客户端可通过一个SUBSCRIBE报文发送多个主题的订阅请求。服务端会针对SUBSCRIBE报文中的所有订阅主题来逐一回复给客户端一个返回码。

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

returnCode-订阅返回码
在这里插入图片描述
另外每一个SUBACK报文也包含有“报文标识符”。MQTT设备可以通过该标识符对报文进行管理。

5.4 UNSUBSCRIBE – 取消订阅

UNSUBSCRIBE报文包含两个重要信息,第一个是取消订阅的主题名称。同一个UNSUBSCRIBE报文可以同时包含多个取消订阅的主题名称。另外,UNSUBSCRIBE报文也包含“报文标识符”,MQTT设备可以通过该标识符对报文进行管理。

当服务端接收到UNSUBSCRIBE报文后,会向客户端发送取消订阅确认报文 – UNSUBACK报文。该报文含有客户端所发送的“取消订阅报文标识符”。

客户端接收到UNSUBACK报文后就可以确认取消主题订阅已经成功完成了。

6.MQTT主题进阶

6.1 主题基本形式

主题的最基本形式就是一个字符串。示例:

  • myTopic
  • motorSpeed
  • MotorSpeed
  • current time

使用主题时需要注意:

  1. 主题是区分大小写的。
  2. 主题可以使用空格。(不建议)
  3. 大部分MQTT服务端是不支持中文主题的,所以我们应使用英文字符ASCII字符来作为MQTT主题。

6.2 主题分级

为了更好的对主题进行管理和分类,我们可以对主题进行分级处理。MQTT主题各个级别之间可以使用”/”来分隔。如下例所示:
在这里插入图片描述
在以上示例中一共有四级主题,分别是第1级 Tyler-1、第2级motor、第三级1、第4级speed。主题的每一级至少需要一个字符,比如以上示例中,数字1既是一级主题。

其他示例:
home/sensor/kitchen/temperature
home/sensor/kitchen/brightness
home/sensor/bedroom/temperature
home/sensor/bedroom/brightness

6.3 主题通配符

当客户端订阅主题时,可以使用通配符同时订阅多个主题。通配符只能在订阅主题时使用,有两种通配符:单级通配符和多级通配符。

1.单级通配符:+

在这里插入图片描述
当客户端订阅了以上主题后,它将会收到以下主题的信息内容:

home/sensor/kitchen/temperature
home/sensor/bedroom/temperature

2.多级通配符

单级通配符仅可代替一个主题级别,而多级通配符”#”可以涵盖任意数量的主题级别。如下示例所示, 多级通配符必须是主题中的最后一个字符
在这里插入图片描述
当客户端订阅了以上含有”#”的主题后,可以收到以下主题的信息。

home/sensor/kitchen/temperature
home/sensor/bedroom/brightness
home/sensor/data

多级通配符可以代替多级主题信息,因此无论”home/sensor”后面有一级还是多级主题,都可以被订阅了”home/sensor/#”的客户端接收到。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.4 主题应用注意事项

1.以$开始的主题

以$开始的主题是MQTT服务端系统保留的特殊主题,不能随意订阅或向其发布信息。

2.不要用“/”作为主题开头

允许使用“/”作为主题的开头,但这毫无意义,而且会额外产生一个没有用处的主题级别。

3.主题中不要使用空格

尽量不要在主题中使用空格或者特殊字符

4.保持主题简洁明了

5.在主题中嵌入客户端ID

在主题中嵌入发布消息的客户端ID,这一操作可以为开发和管理MQTT信息提供便利。通过主题中的客户端ID内容,我们可以很容易了解主题信息是由哪一台设备所发布的。

7.Qos服务质量等级

因为客户端和服务端都可以发布消息和接受消息。为避免混淆,这里使用“发送端”来描述发送MQTT消息的设备,使用“接收端”来描述接受MQTT消息的设备

  1. Qos = 0 - 最多发一次

MQTT服务端和客户端不会对消息传输是否成功进行确认和检查。即Qos为0时,发送端一旦发送完消息后,就完成任务了。这样在环境不稳定的情况下,可能会在传输过程中出现MQTT消息丢失的情况。

  1. Qos = 1 - 最少发一次

发送端在消息发送完成后,会检查接收端是否已经成功接受到了消息。

在这里插入图片描述
接收端成功接收消息后,会发送一条确认报文PUBACK给发送端。如果发送端收到了这条PUBACK确认报文,那么它就知道消息已经成功接收。

假如过了一段时间后,发送端没有收到PUBACK报文,那么发送端会再次发送消息,然后再次等待接收端的PUBACK确认报文。因此,当QoS=1时,发送端在没有收到接收端的PUBACK确认报文以前,会重复发送同一条消息。

在这里插入图片描述
当发送端重复发送一条消息时,PUBLISH报文中的dupFlag会被设置为True。

  1. Qos = 2 - 保证收一次

可以确保接收端只接收一次消息。
发送端需要接收端进行两次消息确认。因此,2级MQTT服务质量是最安全的服务级别,也是最慢的服务级别。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


另外,要想实现QoS>0的MQTT通讯,客户端在连接服务端时必须要将cleanSession设置为false。如果这一步没有实现,那么客户端是无法实现QoS>0的MQTT通讯。

在这里插入图片描述
服务质量降级:对于发布和订阅消息的客户端,服务端会主动采用较低级别的QoS来实现消息传输。

8.保留消息

8.1 发布保留消息的方法

在这里插入图片描述

8.2 修改保留消息

每一个主题只能有一个“保留消息”,如果客户端想要更新“保留消息”,就需要向该主题发送一条新的“保留消息”,这样服务端会将新的“保留消息”覆盖旧的“保留消息”。当有客户端订阅该主题时,服务端就会将最新的“保留消息”发送给订阅客户端了。

8.3 删除保留消息

如果要删除主题的“保留消息”,可以通过向该主题发布一条空的“保留消息”,也就是发送一条0字节payload的“保留消息”。

9.心跳机制

心脏机制就是让客户端在没有向服务端发送信息时,可以定时向服务端发送一条消息。这条用于心跳机制的消息也被称作心跳请求(PINGREQ)

在这里插入图片描述
心跳请求的作用正是用于告知服务端,当前客户端依然在线。服务端在收到客户端的心跳请求后,会回复一条消息。这条回复消息被称作心跳响应(PINGRESP)

在这里插入图片描述
keepAlive数值为60。这就意味着,客户端的心跳间隔时间是60秒。

在这里插入图片描述
在这里插入图片描述
在实际运行中,如果服务端没有在1.5倍心跳时间间隔内收到客户端发布消息(PUBLISH)或发来心跳请求(PINGREQ),那么服务端就会认为这个客户端已经掉线。

举例来说,如果心跳时间间隔是60秒。那么服务端在90秒内没有收到客户端发布的消息也没有收到PINGREQ请求,那么它就会认为客户端已经掉线。

另外,心跳机制不仅仅用于服务端判断客户端是否在线。客户端也可以利用这一机制来判断自己是否与服务端仍保持连接。如果客户端发送了心跳请求(PINGREQ)给服务端一段时间后,仍然没有收到服务端回复的心跳确认。那么客户端也会认为自己已经断开了与服务端的连接。

那么,如果服务端知道了某一台客户端已经掉线,它会采取什么措施吗?

10.MQTT遗嘱

为了让客户端可以更好的发挥作用,便于服务端管理,MQTT协议允许客户端在“活着”的时候就写好遗嘱,这样一旦客户端意外断线,服务端就可以将客户端的遗嘱公之于众。客户端的遗嘱只在意外断线时才会发布,如果客户端正常的断开了与服务端的连接,这个遗嘱机制是不会启动的,服务端也不会将客户端的遗嘱公布。

在这里插入图片描述
当客户端正常断开连接时,会向服务端发送DISCONNECT报文,服务端接收到该报文后,就知道,客户端是正常断开连接,而并非意外断开连接。

在这里插入图片描述

10.1 客户端如何将遗嘱消息发送给服务端

在这里插入图片描述

a.lastWillTopic – 遗嘱主题

遗嘱消息和普通MQTT消息很相似,也有主题和正文内容。lastWillTopic的作用正是告知服务端,本客户端的遗嘱主题是什么。只有那些订阅了这一遗嘱主题的客户端才会收到本客户端的遗嘱消息。

以上图为例,此遗嘱主题为”hans/will”。也就是说,只有订阅了主题”hans/will”的客户端,才会收到这台客户端的遗嘱消息。

b.lastWillMessage – 遗嘱消息

遗嘱消息定义了遗嘱消息内容。在本示例中,那些订阅了主题”hans/will”的客户端会在客户端意外断线时,收到服务端发布的“unexpected exit”。

c.lastWillQoS – 遗嘱QoS

对于遗嘱消息来说,同样可以使用服务质量来控制遗嘱消息的传递和接收。这里的服务质量与普通MQTT消息的服务质量是一样的概念。也可以设置为0、1、2。对于不同的服务质量级别,服务端会使用不同的服务质量来发布遗嘱消息。

d.lastWillRetain – 遗嘱保留

遗嘱保留用于设置遗嘱消息是否需要进行保留处理。服务端会根据此处内容,对遗嘱消息进行相应的保留与否处理。

10.2 MQTT遗嘱操作建议

假设我们现在有一台MQTT客户端。它的client id是 client-1。它的遗嘱主题是“client-1-will”

  1. 当client-1连接服务端时,CONNECT报文中的遗嘱消息是“offline”。并且它的遗嘱保留设置为true。

  2. 当client-1成功连接服务端后,立即向遗嘱主题“client-1-will”发布一条消息“online”。同时在发布此消息时,保留标志设置为true。这样,只要client-1在线,那么任何设备一订阅“client-1-will”就能收到设备在线的消息“online”。

  3. 如果client-1发生意外离线。那么任何设备一订阅“client-1-will”就会收到设备离线的消息”offline”。

  4. 如果client-1恢复连接,那么它会将遗嘱主题“client-1-will”的保留消息更改为“online”,这样任何设备一订阅“client-1-will”就能收到设备在线的消息“online”。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

11.MQTT用户密码认证

在这里插入图片描述
上图中红色方框所标注的username(用户名)和password(密码)。这里的用户名和密码是用于客户端连接服务端时进行认证需要的。

有些MQTT服务端需要客户端在连接时提供用户名和密码。只有客户端正确提供了用户名和密码后,才能连接服务端。否则服务端将会拒绝客户端连接,那么客户端也就无法发布和订阅消息了。

请注意,username(用户名)和password(密码)是可选的CONNECT信息。也就是说,有些服务端开启了客户端用户密码认证,这种服务端需要客户端在连接时正确提供认证信息才能连接。当然,那些没有开启用户密码认证的服务端无需客户端提供用户名和密码认证信息。

用户名和密码除了有以上功能外,有些公用MQTT服务端也利用此信息来识别客户端属于哪一个用户,从而对客户端进行管理。比如用户可以拥有私人主题,这些主题只有该用户可以发布和订阅。对于私人主题,服务端就可以利用客户端连接时的用户名和密码来判断该客户端是否有发布订阅该用户私人主题的权限。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


EMQ

5G 时代,万物互联消息引擎

Broker 文档

EMQ X (Erlang/Enterprise/Elastic MQTT Broker) 是基于 Erlang/OTP 平台开发的开源物联网 MQTT 消息服务器。

Erlang/OTP是出色的软实时 (Soft-Realtime)、低延时 (Low-Latency)、分布式 (Distributed)的语言平台。

MQTT 是轻量的 (Lightweight)、发布订阅模式 (PubSub) 的物联网消息协议。

EMQ X 设计目标是实现高可靠,并支持承载海量物联网终端的MQTT连接,支持在海量物联网设备间低延时消息路由:

  1. 稳定承载大规模的 MQTT 客户端连接,单服务器节点支持50万到100万连接。
  2. 分布式节点集群,快速低延时的消息路由,单集群支持1000万规模的路由。
  3. 消息服务器内扩展,支持定制多种认证方式、高效存储消息到后端数据库
  4. 完整物联网协议支持,MQTT、MQTT-SN、CoAP、LwM2M、WebSocket 或私有协议支持。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启动后,在地址栏输入:
在这里插入图片描述
用户名:admin,密码:public
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
基本过了一遍,剩下的就是在项目里整合实践了。


闲谈

在这里插入图片描述

最近喜欢上了格拉祖诺夫的作品,他的音乐美而清澈,很适合休憩的时候欣赏。

大华尔兹音乐会,Op. 41

罗沛霖院士谈同学钱学森:“他拿着这钱去,跑到南京路,南京路有外国商店可以买到唱片,买了一套格拉祖诺夫的《音乐会圆舞曲》。一个本子里面有两张唱片,拿到我这儿来一块听。当时我问他,你怎么喜欢格拉祖诺夫,他说,因为他的色彩丰富啊。”

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值