MQTT 协议
视频说明:https://www.bilibili.com/video/BV1qf4y1n7js?p=2
参考:http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-tuttorial/mqtt-tutorial/
官网
MQTT 是物联网(Internet of Things,IoT)的 OASIS 标准消息传递协议。它被设计为一个极其轻量级的发布/订阅消息传输,非常适合用较小的代码占用和最小的网络带宽连接远程设备。
官网链接
🟠 MQTT 入门:https://www.hivemq.com/blog/how-to-get-started-with-mqtt/
🟠 MQTT 协议初学者指南:http://www.steves-internet-guide.com/mqtt/
🟠 MQTT 3.1.1 规范:http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
🟠 MQTT 5 规范:https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html
Github链接
💜 brokers:https://github.com/mqtt/mqtt.org/wiki/brokers
💜 servers:https://github.com/mqtt/mqtt.org/wiki/servers
💜 public_brokers:https://github.com/mqtt/mqtt.org/wiki/public_brokers
💜 Client libraries:https://github.com/mqtt/mqtt.org/wiki/libraries
💜 tools:https://github.com/mqtt/mqtt.org/wiki/tools
可参考
🧊 MQTT协议中文版:https://mcxiaoke.gitbooks.io/mqtt-cn/content/
🧊 MQTT协议的优缺点:https://zhuanlan.zhihu.com/p/268113708
为什么是 MQTT?
轻巧高效
MQTT 客户端非常小,需要的资源最少,因此可以在小型微控制器上使用。MQTT 消息头很小以优化网络带宽。
双向通讯
MQTT 允许在设备到云和云到设备之间进行消息传递。这使得向一组事物广播消息变得容易。
扩展到数以百万计的事物
MQTT 可以扩展以连接数百万个物联网设备。
可靠的消息传递
消息传递的可靠性对于许多物联网用例很重要。这就是 MQTT 定义了 3 个服务质量级别的原因:
0 - 最多一次,
1 - 至少一次,
2 - 恰好一次
支持不可靠的网络
许多物联网设备通过不可靠的蜂窝网络连接。MQTT 对持久会话的支持减少了客户端与代理重新连接的时间。
启用安全
MQTT 使使用 TLS 加密消息和使用现代身份验证协议(例如 OAuth)对客户端进行身份验证变得容易。
MQTT说明
MQTT 版本
🟣 1999年,IBM的Andy Stanford-Clark博士以及Arcom公司ArlenNipper博士发明了MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)技术 。虽然叫做消息队列遥测传输,但它与消息队列毫无关系,而是使用了一个发布和订阅的模型。
🟣 2014年10月,MQTT v3.1.1正式发布,与此同时 v3.1.1 成为OASIS协议标准(理解为:正式成为开放协议)。
🟣 2018年5月,MQTT v5.0正式发布,2019年3月,v5.0 成为了新的 OASIS 标准。
v5.0 在 v3.1.1的基础上做了较大的改变且不向下兼容。也就是 版本5.0 相对于 版本3.1.1 增加了很多新特性。
MQTT v3.1.1是常用的版本。
🍄 最近发现好多 mqtt 的服务端(broker)支持 3.1.1 和 5.0 两个版本协议的同时连接,也就是 3.1.1 的客户端和 5.0 版本的客户端有共同的订阅树。
🍄 但是版本 3.1.1 和 5.0 还是不兼容的。
MQTT和Websocket的区别
🟣 MQTT:是为了物联网场景设计的基于TCP的Pub/Sub协议(MQTT over TCP),有许多为物联网优化的特性,比如适应不同网络的QoS、层级主题、遗言等等。
🟣 WebSocket:是为了HTML5应用(浏览器)方便与服务器 双向通讯而设计的协议,HTTP握手然后转TCP协议,用于取代之前的Server Push、Comet、长轮询等老旧实现。
🟣 场景:浏览器作为MQTT的客户端,设备也作为MQTT的客户端,通过WebSocket通信,即 MQTT over WebSocket 。
可以这样理解:MQTT是内容格式,是应用层协议,WebSocket和TCP类似,是传输协议,可以传输MQTT格式的内容,也可以是其他格式的内容。
MQTT主题
主题的最基本形式就是一个字符串。
- 主题是区分大小写的。
- 主题可以使用空格,建议不要在主题中使用空格
主题分级
- MQTT主题各个级别之间可以使用
/
来分隔。
主题通配符
- 单级通配符:
+
- 多级通配符:
#
sensor/+/temperature
将匹配
sensor/sn1/temperature
sensor/sn2/temperature
sensor/#
将匹配
sensor/sn1/temperature
sensor/sn2/abc
sensor/123
QoS 服务质量等级
- QoS = 0 – 最多发一次
- QoS = 1 – 最少发一次
- QoS = 2 – 保证收一次
发布是2,订阅是1,那服务端按1来转发
发布是0,订阅是1,那服务端按0来转发
服务端按低的那个标准来转发消息
保留消息
服务端保留一条该主题的消息,只有一条
- 当客户端订阅该主题时,会收到这个消息
- 更新消息:发个新消息到该主题,即覆盖上一条
- 删除消息:发个空消息到该主题
心跳机制
服务端可以观察硬件设备是否在线
🟣 客户端连接时上报 keepAlive 时间,即心跳时间间隔
🟣 客户端发布了消息,那就重新计算时间
🟣 客户端没有发布消息,那就等到心跳时间间隔到了,发送 PINGREQ
消息到服务端,服务端回复 PINGRESP
🟠 服务端在1.5倍心跳时间间隔时还没收到客户端的消息,即认定客户端已经断开连接
🟠 客户端发送 PINGREQ
消息到服务端,一段时间后仍没有收到服务端的回复,那么客户端认定和服务端断开了
MQTT遗嘱
客户端正常断开连接时,会发送 DISCONNECT
报文
客户端意外断开时,比如网断了,可能没电了,服务端会将遗嘱发送给订阅这个遗嘱主题的客户端
设置遗嘱消息:客户端连接时设置,包括遗嘱主题、遗嘱消息、遗嘱Qos,遗嘱保留,和普通消息类似
操作建议:
- 客户端ID:client-1
- 遗嘱主题:client-1-will
- 遗嘱消息:offline
- 遗嘱Qos:2
- 遗嘱保留:true
效果:上报客户端意外断开了
- 连接时:客户端向遗嘱主题
client-1-will
发送 “online”,订阅client-1-will
的客户端会收到 “online” - 意外离线时:订阅
client-1-will
的客户端会收到 “offline” - 恢复连接时:客户端向遗嘱主题
client-1-will
发送 “online”,订阅client-1-will
的客户端会收到 “online”
MQTT用户密码认证
username(用户名)和password(密码)是可选的CONNECT信息
也就是说,有些服务端开启了客户端用户密码认证,这种服务端需要客户端在连接时正确提供认证信息才能连接。