Mqtt概述
Mqtt开发最初是用于卫星通讯监控输油管道的项目。一种用于嵌入式设备的通讯协议,这种通讯协议必须满足以下条件:
- 易于实现
- 数据传输的服务质量可控
- 占用带宽小
- 传输数据内容不可预知
- 设备连接状态可知
MQTT 从诞生之初就是专为低带宽、高延迟或不可靠的网络而设计的。历经几十年的更新和变化,以上这些特点仍然是MQTT协议的核心特点。并从嵌入式系统应用拓展到开放的物联网(IoT)领域
MQTT主流版本有两个 MQTT3.1.1和MQTT5。MQTT3.1.1是在2014年10月发布的,而MQTT5是在2019年3月发布的。在此文档编写时间(2021年7月)MQTT3.1.1仍然主流版本。
MQTT5是在MQTT3.1.1的基础上添加了更多的功能补充完善MQTT协议。
MQTT 通信协议和其他MQ协议类似有三个重要角色,客户端,服务端,主题。和其他具有发布订阅的通信协议一样。通过这三个角色来实现,生产者消费者模型,并通过主题来完成信息隔离,资源分离等功能。只是MQTT协议在设计时报文更加精简。
Mqtt 协议基础
mqtt报文示例
MQTT运行于TCP层之上并以明文方式传输,这就相当于HTTP的明文传输,使用Wireshark可以完全看到MQTT发送的所有消息,消息指令如下。
通过此示例可以了解一个初步印象,下面将分别讲述这些报文的含义
mqtt 消息格式
每条MQTT命令消息由固定报文头 | 可变报文头 | 负荷 这三部分组成
-
固定报文头(Fixed Header)
MQTT固定报文头最少有两个字节,第一字节包含消息类型(Message Type)和QoS级别等标志位。第二字节开始是剩余长度字段,该长度是后面的可变报文头加消息负载的总长度,该字段最多允许四个字节。
-
可变报文头(Variable Header)
可变报文头主要包含协议名、协议版本、连接标志(Connect Flags)、心跳间隔时间(Keep Alive timer)、连接返回码(Connect Return Code)、主题名(Topic Name)等。也算mqtt的协议的主要部分
-
有效负荷(Payload)
实际上可以理解为消息主体(body)。当MQTT发送的消息类型是CONNECT(连接)、PUBLISH(发布)、SUBSCRIBE(订阅)、SUBACK(订阅确认)、UNSUBSCRIBE(取消订阅)时,则会带有负荷。
MQTT的消息类型(Message Type)
MQTT协议拥有14种不同的消息类型,可简单分为连接及终止、发布和订阅、QoS 2消息的机制以及各种确认ACK。类型类型是0-15的数字,
每个消息数字与其对应的消息类型含义如下:
public final static int MQTT_CONNECT = 1; //请求连接
public final static int MQTT_CONNACK = 2; //请求应答
public final static int MQTT_PUBLISH = 3; //发布消息
public final static int MQTT_PUBACK = 4; //发布应答
public final static int MQTT_PUBREC = 5; //发布已接收,保证传递1
public final static int MQTT_PUBREL = 6; //发布释放,保证传递2
public final static int MQTT_PUBCOMP = 7; //发布完成,保证传递3
public final static int MQTT_SUBSCRIBE = 8; //订阅请求
public final static int MQTT_SUBACK = 9; //订阅应答
public final static int MQTT_UNSUBSCRIBE = 10; //取消订阅
public final static int MQTT_UNSUBACK = 11; //取消订阅应答
public final static int MQTT_PINGREQ = 12; //ping请求
public final static int MQTT_PINGRESP = 13; //ping响应
public final static int MQTT_DISCONNECT = 14; //断开连接