本文将简要介绍MQTT协议的特点,并列出常用MQTT库
MQTT协议
基本介绍
基于TCP/IP协议,全称Message Queuing Telemetry Transport,消息队列遥测传输协议,采用基于Topics(主题)的Publish(发布)/Subscribe(订阅)进行信息交换,依赖于Broker(代理或服务器)。
官方网站:=> mqtt.org
常用开源协议库:
- 来自Eclipse IOT的paho.mqtt.embedded-c库,该库提供用于嵌入式设备的MQTT(Public or Subscribe)客户端实现
- 同样来自Eclipse的Eclipse Mosquitto,提供MQTT协议5.0、3.1.1和3.1版的服务器开源实现
- 用于Node.js或浏览器的MQTT客户端库,使用Javascript编写的mqtt.js库以及该库的异步版本 async-mqtt(使用Promise对象而不是回调)
特性
- 使用发布(Publish)/订阅(subscribe)消息模式,提供一对多的消息发布,解除应用程序耦合
- 对负载(Payload)内容屏蔽的消息传输
- 一般基于TCP/IP协议进行数据传输,但是也有基于UDP的版本(MQTT-SN)
- 有三种消息发布服务质量(至少一次、至多一次、只有一次)
- 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量
- 使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制
Qos(服务质量)
MQTT协议提供三种QoS(Quality of Service,服务质量)用于保证消息传递的次数,用3个Bit表示,如下所示:
- Service 0(最多一次):消息发布者只会发送一次消息
- Service 1(最少一次):消息发布者会重复发送消息,直到从代理获得确认消息
- Service 2(只有一次):消息发布者只发送一次消息,但是会通过四次握手来确认消息被收到
包体结构
在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、可变头(Variable header)、消息体(payload)三部分构成。MQTT数据包结构如下:
- 固定头(Fixed header):一般为2个字节,存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识。
- 可变头(Variable header):存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。
- 消息体(Payload):存在于部分MQTT数据包中,表示客户端收到的具体内容。
Topics(主题)
MQTT客户端通过在代理或服务器端,以subscribe(订阅)的形式来获取信息
Topics(主题)在MQTT协议中,为字符串值,以/
进行划分,例如hw/room1/temp1
表示1号房间的1号传感器,订阅者可以使用通配符+
或#
来接收来自多个主题的消息。
Payload(负载)
Plaload(负载)或称为消息体,是MQTT数据包的第三部分,共有CONNECT
、SUBSCRIBE
、SUBACK
、UNSUBSCRIBE
四种类型的消息
CONNECT
:消息体内容主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码。SUBSCRIBE
:消息体内容是一系列的要订阅的主题以及QoS。SUBACK
:消息体内容是服务器对于SUBSCRIBE
所申请的主题及QoS进行确认和回复。UNSUBSCRIBE
:消息体内容是要订阅的主题。
Last Will and Testament(遗嘱)
在 MQTT 中,使用Last Will and Testament (LWT) 功能将异常断开的客户端通知其他客户端。每个客户端在连接到代理时都可以指定其最后的遗言,遗言是一条普通的 MQTT 消息。
代理将会存储消息,直到它检测到客户端不正常地断开连接。为了响应不正常的断开连接,代理将 last-will 消息发送到 last-will 消息主题的所有订阅客户端。如果客户端使用正确的 DISCONNECT 消息正常断开连接,则代理将丢弃存储的 LWT 消息。
LWT 可帮助您在客户端连接断开时实施各种策略(或至少通知其他客户端离线状态)。