MQTT 协议

视频说明:https://www.bilibili.com/video/BV1qf4y1n7js?p=2

参考:http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-tuttorial/mqtt-tutorial/

官网

https://mqtt.org/

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信息

也就是说,有些服务端开启了客户端用户密码认证,这种服务端需要客户端在连接时正确提供认证信息才能连接。

posted @ 2021-09-16 16:05  ioufev  阅读(1768)  评论(0编辑  收藏  举报