初出茅庐的小李第28篇博客之MQTT学习笔记

物联网学习入门篇之MQTT协议

MQTT: Massage Queuing Telemetry Transport,消息队列遥测传输
MQTT是基于互联网的基础协议TCP/IP协议而构建的,由IBM在1999年发布,基于发布和订阅两种模式(publish/subscribe)算是一种轻量级通讯协议,在2014年成为了OASIS开放标准,很多语言都支持该协议。
MQTT特点:
发布订阅模式,一对多消息发布
开放消息协议,简单容易实现
有三种消息服务质量:
至多一次 会发生消息丢失或者重复 上报数据丢失一次影响不是很大
至少一次 确保消息到达但消息重复可能会发生。
只有一次 确保消息到达一次。即时通讯类或者计费类。

Last Will:遗言机制,用于通知同一主题下的其它设备发送遗言的设备已经断开了连接。
Testament:遗嘱机制。
三种身份:
Publish发布者
Broker 代理者(服务器)
Subscribe订阅者
发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者

MQTT传输的消息分为:主题(Topic)和负载(payload)

主题可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题(Topic)下的
消息内容既是负载(payload)。
负载(payload)可以理解为消息的内容,是指订阅者具体要使用的内容

MQTT会构建底层的网络传输,它将建立客户端到服务器的连接,提供两者之前有序的,无
损的,基于字节流的双向传输。当应用数据通过MQTT网络发送时,MQTT会把与之相关
的服务质量(QoS)和主题名(Topic)相关联。
MQTT的客户端如何定义?
它是一个使用MQTT协议的应用程序或者设备,它总是建立到服务器的网络连接。客户端
可以:
(1) 发布其它客户端可能订阅的消息主题。
(2) 订阅其它客户端发布的消息主题
(3) 退订或者删除应用程序的消息
(4) 断开与服务器的连接
MQTT的服务器如何定义?
MQTT的服务器被称之为“消息代理”也就是“Broker”这个词的由来,它可以是一个应用程序或者一台设备。它位于消息发布者和订阅者之间。
(1) 接受来自客户端的网络连接
(2) 接受客户发布的应用信息
(3) 处理来自客户端的订阅和退订请求
(4) 向订阅的客户端转发应用程序消息

订阅:
订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话中每个订阅都有一个不同的主题筛选器。
会话(Session)每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互,会话存在于一个网络之间,也可能在客户端和服务端之间跨越多个连续的网络连接。
主题名字(Topic Name)
连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。
主题筛选器(Topic Filter)
一个对主题名通配符的筛选器,在订阅表达式中使用,表示订阅所匹配的多个主题。
负载(Payload)
消息订阅者所具体接收的内容

MQTT协议中的方法:
也就是一些动作的名称用来表示对资源的操作,这个资源可以代表预先存在的数据或动态生成的数据,这取决于服务器的实现。
(1) Connect 等待与服务器建立连接。
(2) Disconecet 等待MQTT客户端完成所做的工作,并与服务器断开TCP/IP会话。
(3) Subscribe 等待完成订阅
(4) UnSubscribe 等待服务器取消客户端的一个或多个topics订阅
(5) Publish MQTT客户端发送消息请求,发送完成后返回应用程序线程

MQTT数据包结构
固定包头(Fixed header)
所有的MQTT数据包里都要有,表示数据包类型及数据包的分组类标识。

可变头 (Variable header)
不是都需要有,取决于数据包类型,数据包类型决定了可变头是否存在以及存在的内容

消息体 (payload)
存在部分数据包,表示客户收到的具体内容

初出茅庐的小李第28篇博客之MQTT学习笔记_第1张图片
初出茅庐的小李第28篇博客之MQTT学习笔记_第2张图片
4位数据包类型,不同类型具体标识也是4位
初出茅庐的小李第28篇博客之MQTT学习笔记_第3张图片
有16种情况,其中两种不可用,还剩14种情况,有好几个是成对的数据包类型
初出茅庐的小李第28篇博客之MQTT学习笔记_第4张图片
(1) DUP:发布消息的副本。用来在保证消息的可靠传输,如果设置为1,则在下面的变长中增加MessageId,并且需要回复确认,以保证消息传输完成,但不能用于检测消息重复发送。
(2)QoS:发布消息的服务质量,即:保证消息传递的次数
Ø00:最多一次,即:<=1
Ø01:至少一次,即:>=1
Ø10:一次,即:=1
Ø11:预留
(3)RETAIN: 发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果没有那么推送至当前订阅者后释放。
固定头的第二字节用来保存变长头部和消息体的总大小的,但不是直接保存的。这一字节是可以扩展,其保存机制,前7位用于保存长度,后一部用做标识。当最后一位为1时,表示长度不足,需要使用二个字节继续保存。
初出茅庐的小李第28篇博客之MQTT学习笔记_第5张图片
很多类型数据包中都包括一个2字节的数据包标识字段,这些类型的包有:PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。
Payload消息体位MQTT数据包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息:

(1)CONNECT,消息体内容主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码。
(2)SUBSCRIBE,消息体内容是一系列的要订阅的主题以及QoS。
(3)SUBACK,消息体内容是服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。
(4)UNSUBSCRIBE,消息体内容是要取消订阅的主题。
基本概念 Basic Conception
Session 会话
定义
• 定义:某个客户端(由ClientID作为标识)和某个服务器之间的逻辑层面的通信
• 生命周期(存在时间):会话 >= 网络连接
ClientID
• 客户端唯一标识,服务端用于关联一个Session
• 只能包含这些 大写字母,小写字母 和 数字(0-9a-zA-Z),23个字符以内
• 如果 ClientID 在多次 TCP连接中保持一致,客户端和服务器端会保留会话信息(Session)
• 同一时间内 Server 和同一个 ClientID 只能保持一个 TCP 连接,再次连接会踢掉前一个
CleanSession 标记
• 在Connect时,由客户端设置
• 0 —— 开启会话重用机制。网络断开重连后,恢复之前的Session信息。需要客户端和服务器有相关Session持久化机制。
• 1 —— 关闭会话重用机制。每次Connect都是一个新Session,会话仅持续和网络连接同样长的时间。
客户端 Session
• 已经发送给服务端,但是还没有完成确认的 QoS 1 和 QoS 2 级别的消息
• 已从服务端接收,但是还没有完成确认的 QoS 2 级别的消息
服务器端 Session
• 会话是否存在,即使会话状态的其它部分都是空 (SessionFlag)
• 客户端的订阅信息 (ClientSubcription)
• 已经发送给客户端,但是还没有完成确认的 QoS 1 和 QoS 2 级别的消息
• 即将传输给客户端的 QoS 1 和 QoS 2 级别的消息
• 已从客户端接收,但是还没有完成确认的 QoS 2 级别的消息
• (可选)准备发送给客户端的 QoS 0 级别的消息
长连接维护与管理
Keep Alive 心跳
• 目的是保持长连接的可靠性,以及双方对彼此是否在线的确认。
• 客户端在Connect的时候设置 Keep Alive 时长。如果服务端在 1.5 * KeepAlive 时间内没有收到客户端的报文,它必须断开客户端的网络连接
• Keep Alive 的值由具体应用指定,一般是几分钟。允许的最大值是 18 小时 12 分 15 秒
Will 遗嘱
• 遗嘱消息(Will Message)存储在服务端,当网络连接关闭时,服务端必须发布这个遗嘱消息,所以被形象地称之为遗嘱,可用于通知异常断线。
• 客户端发送 DISCONNECT 关闭链接,遗嘱失效并删除
• 遗嘱消息发布的条件,包括:
• 服务端检测到了一个 I/O 错误或者网络故障
• 客户端在保持连接(Keep Alive)的时间内未能通讯
• 客户端没有先发送 DISCONNECT 报文直接关闭了网络连接
• 由于协议错误服务端关闭了网络连接
• 相关设置项,需要在Connect时,由客户端指定
• Will Flag —— 遗嘱的总开关
• 0 – 关闭遗嘱功能,Will QoS 和 Will Retain 必须为 0
• 1 – 开启遗嘱功能,需要设置 Will Retain 和 Will QoS
• Will QoS —— 遗嘱消息 QoS
• 可取值 0、1、2,含义与消息QoS相同
• Will Retain —— 遗嘱是否保留
• 0 – 遗嘱消息不保留,后面再订阅不会收到消息
• 1 – 遗嘱消息保留,持久存储
• Will Topic —— 遗嘱话题
• Will Payload —— 遗嘱消息内容
消息基本概念
报文标识 Packet Identifier
• 存在报文的可变报头部分,非零两个字节整数 (0-65535]
• 一个流程中重复:这些报文包含 PacketID,而且在一次通信流程内保持一致:
• PUBLISH(QoS>0 时),PUBACK,PUBREC,PUBREL,PUBCOMP
• SUBSCRIBE, SUBACK
• UNSUBSCIBE,UNSUBACK
• 新的不重复:客户端每次发送一个新的这些类型的报文时都必须分配一个当前 未使用的PacketID
• 当客户端处理完这个报文对应的确认后,这个报文标识符就释放可重用。
• 独立维护:客户端和服务端彼此独立地分配报文标识符。因此,客户端服务端组合使用相同的报文标识符可以实现 并发 的消息交换。可能出现一下情况,并不算异常:

Payload 有效载荷,消息体
• 最大允许 256MB
• Publish 的 Payload 允许为空。在很多场合下,代表将持久消息(或者遗嘱消息)清空。
• UTF-8编码
Retain 持久消息(粘性消息)
• RETAIN 标记:每个Publish消息都需要指定的标记
• 0 —— 服务端不能存储这个消息,也不能移除或替换任何 现存的保留消息
• 1 —— 服务端必须存储这个应用消息和它的QoS等级,以便它可以被分发给未来的订阅者
• 每个Topic只会保留最多一个 Retain 持久消息
• 客户端订阅带有持久消息的Topic,会立即受到这条消息
• 服务器可以选择丢弃持久消息,比如内存或者存储吃紧的时候
• 如果客户端想要删除某个Topic 上面的持久消息,可以向这个Topic发送一个Payload为空的持久消息
• 遗嘱消息(Will)的Retain持久机制同理
QoS 服务等级(消息可靠性)

最多一次 At most Once(QoS == 0)

没有回复,不需要存储。有可能丢失(网络异常断开,业务层繁忙或者错误)
至少一次 At least Once(QoS == 1 )
笔记参考了大神博客地址如下
https://blog.csdn.net/aa1215018028/article/details/84888096

你可能感兴趣的:(笔记)