前言
实习公司主要项目为物业项目,其中包含了物业所有相关业务,包括硬件设备例如大门,闸机,摄像头等控制。项目中需要使用MQTT协议进行控制
1 MQTT协议介绍
MQTT
协议全称是(Message Queuing Telemetry Transport),即消息队列遥测传输协议。- 是一种基于
发布/订阅(Publish/Subscribe)
模式的轻量级通讯协议,并且该协议构建于TCP/IP
协议之上 - 由于TCP协议本身的可靠性,使其具备了
高可靠
的特点 - 又因为MQTT协议传输的最小的报文也只有两个字节,所以还具备
低开销
的特点 - MQTT传输的消息分为:主题(Topic)和负载(payload)两部分
- Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)
- payload,可以理解为消息的内容,是指订阅者具体要使用的内容
1.2 发布/订阅
-
在通信过程中存在三种不同身份,
发布者
,代理(服务器)
,订阅者
,发布者将消息发布到代理服务器上,代理服务器将分发给订阅该消息的订阅者 -
发布者和订阅者都是客户端,服务端为代理,两个客户端可以相互订阅
-
MQTT协议通信模型
2. 关于MQTT的术语
-
应用消息 Application Message
MQTT 协议通过网络传输应用数据。应用消息通过 MQTT 传输时,它们有关联的服务质量(QoS) 和主题(Topic) 。
-
订阅 Subscription
订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器。
-
主题名 Topic Name
附加在应用消息上的一个标签,服务端已知且与订阅匹配。服务端发送应用消息的一个副本给每一个匹配的客户端订阅。
-
主题过滤器 Topic Filter
订阅中包含的一个表达式,用于表示相关的一个或多个主题。主题过滤器可以使用通配符。
-
会话 Session
客户端和服务端之间的状态交互。一些会话持续时长与网络连接一样,另一些可以在客户端和服务端的多个连续网络连接间扩展。
-
控制报文 MQTT Control Packet
通过网络连接发送的信息数据包。MQTT规范定义了十四种不同类型的控制报文,其中一个(PUBLISH报文) 用于传输应用消息。
3 MQTT参数机制
3.1 消息质量(QoS)
MQTT消息质量有三个等级,QoS 0
,QoS 1
和 QoS 2
。
-
QoS 0:最多分发一次。客户端只发送一次消息,不保证消息是否送达,可用于定时更新数据且数据不重要的场景,例如:温度传感器。
-
QoS 1:至少分发一次。发送方向服务器发送消息,如果发送异常,在指定时间没收到PUBACK就会进行重新发放,直到服务器接收并返回PUBACK,保证消息送达,但可能由于网络波动送达多次重复消息,可适用于重复消息不会影响结果的场景,例如:各种解锁场景。(保证交付功能)
-
QoS 2:只分发一次。保证消息送达并且不重复,使用这个服务质量等级会有额外的开销。例如,这个等级可用在一个计费系统中,这里如果消息重复或丢失会导致不正确的收费。
- 发送端向接收端发送 PUBLISH 报文
- 接收端接收到 PUBLISH 报文后,向发送端回复一个 PUBREC 报文(官方称其为–发布收到)
- 发送端接收到 PUBREC 报文后,会再次向接收端发送 PUBREL 报文(官方称其为–发布释放)
- 接收端接收到 PUBREL 报文后,会再次向发送端回复一个 PUBCOMP 报文(官方称其为–发布完 成)
如果发送端接收到 PUBCOMP 报文表示消息传输成功,它确认接收端已经成功接收到消息,整个过 程结束
3.2 保留消息
-
通过PUBLISH报文中的retain标志设置,是一个bool值
-
作用
-
可以使订阅了带有保留消息主题的客户端上线后就能接收到主题信息。
-
例如,假设主题的发布者在整点(例如7:00)时会向服务器发送室温。 当7:15的时候有一个订阅了该主题的客户端上线了。 1、主题发布者没有设置保留消息,则新上线的客户端是没有办法接收到7点时的室温温度的,只能等到8:00时才能接收到室温 2、主题发布者设置保留消息,则新上线的客户端,上线后能接收到7:00时的室温信息的。
-
-
更新保留消息
- 每一个主题只能有一个“保留消息”,如果客户端想要更新“保留消息”,就需要向该主题发送一条新的“保留消息”,这样服务端会将新的“保留消息”覆盖旧的“保留消息”。当有客户端订阅该主题时,服务端就会将最新的“保留消息”发送给订阅者。
-
删除保留消息
- 要向该主题发布一条空的“保留消息”。
3.3 心跳机制
-
通过keepAlive设置
用来保持和服务器的链接,有些客户端只是消息的订阅者或者是不经常向服务器发布主题,这时就需要心跳机制来保持与服务器的链接了。
-
心跳机制原理
让客户端在没有向服务端发送消息的这个空闲时间里,定时向服务端发送一个心跳包,这个心跳包被称为心跳请求,其实质就是向服务端发送一个 PINGREQ 报文;当服务端收到PINGREQ 报文后就知道该客户端依然在线,然后向客户端回复一个 PINGRESP 报文,称为心跳响应
-
消息传输情况
心跳是定时发送的,服务器知道客户端每个多少秒会向服务器发送心跳,服务器一旦未收到客户端的心跳包,就知道客户端可能断线了。客户端可以通过心跳包判断自己与服务器是否断开链接。
3.4 遗嘱机制
-
客户端与服务器断开链接的两种方式
- 客户端主动向服务端发送 DISCONNECT 报文,请求断开连接,自然服务端也就知道了客户端要离线了;
- 客户端意外掉线。被动与服务端断开了连接。
遗嘱机制是在意外掉线是使用的。一旦客户端意外断线,服务端就可以将客户端的遗嘱公之于众。
-
设置遗嘱
遗嘱消息和普通 MQTT 消息很相似,也有主题和正文内容 在客户端连接服务端时的CONNECT报文中设置。CONNECT报文如下:
willTopic – 遗嘱主题 告知服务端,本客户端的遗嘱主题是什么。只有那些订阅了这一遗嘱主题的客户端才会收到本客户端的遗嘱消息。
willMessage – 遗嘱消息 遗嘱的内容。
willRetain – 遗嘱消息的保留标志 遗嘱消息也可以设置为保留标志,用于告诉服务端是否需要对遗嘱消息进行保留处理
willQoS – 遗嘱消息的 QoS 这里的服务质量与普通MQTT 消息的服务质量是一样的概念
3.5 用户密码认证
同样存在于CONNECT报文中
上图中红框所示的两个参数:username(用户名)和 password(密码),这里的用户名和密码是客户端连接服务端时进行认证所需要的。