Message Queuing Telemetry Transport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与 HTTP 一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。
(1)MQTT协议身份和消息格式
有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
MQTT传输的消息分为:主题(Topic)和负载(payload)两部分
①Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)
②payload,消息的内容
(2)网络传输与应用消息
MQTT会构建底层网络传输:它将建立客户端到服务器的连接,提供两者之间的一个有序的、无损的、基于字节流的双向传输。
(3)MQTT客户端作用
①发布其他客户端可能会订阅的信息
②订阅其它客户端发布的消息
③退订或删除应用程序的消息
④断开与服务器连接
(4)MQTT服务端作用
可以是一个应用程序或一台设备
①接受来自客户的网络连接
②接受客户发布的应用信息
③处理来自客户端的订阅和退订请求
④向订阅的客户转发应用程序消息
(5)MQTT协议中的订阅、主题、会话
订阅(Subscription):
订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器会话(Session):
每个客户端与服务器建立连接后就是一个会话
主题名(Topic Name):
就是连接到一个应用程序消息的一个标签。该标签与服务器的订阅的相匹配,服务器会将消息发送给订阅所匹配标签的每个客户端。
主题筛选器(Topic Filter):
表示订阅所匹配到的多个主题
负载(Payload):
其实就是内容。消息订阅者所具体接收的内容
二、MQTT协议的特点
轻量、简单、开放,是低开销、低带宽占用的即时通讯协议。使用场景有:机器与机器(M2M)、物联网(IoT)。MQTT协议当前版本为,2014年发布的MQTT v3.1.1。除标准版外,还有一个简化版MQTT-SN,该协议主要针对嵌入式设备,这些设备一般工作于TCP/IP网络,如ZigBee
(1)使用的发布/订阅消息模式,它提供了一对多消息分发,以实现与应用程序的解耦。
(2)对负载内容屏蔽的消息传输机制。
(3)对传输消息有三种服务质量(QoS)
①QoS0:最多一次,这一级别会发生消息丢失或重复,消息发布依赖于底层TCP/IP网络。即:<=1
②QoS1:最少一次(承诺消息将至少传送一次给订阅者),这一级别会确保消息到达,但消息可能会重复。即:>=1
③QoS2:只有一次(承诺消息仅传送到目的地一次),确保消息只有一次到达。即:=1。在一些要求比较严格的计费系统中,可以使用此级别。
(注意:带有唯一消息 ID 的消息会存储两次,首先来自发送者,然后是接收者。QoS 级别 2 在网络中具有最高的开销,因为在发送方和接收方之间需要两个流)
数据传输和协议交换的最小化(协议头部只有2字节),以减少网络流量;
通知机制,异常中断时通知传输双方;
比如目前流行的共享单车智能锁,智能锁可以定时使用QoS level 0质量消息请求服务器,发送单车的当前位置,如果服务器没收到也没关系,反正过一段时间又会再发送一次。之后用户可以通过App查询周围单车位置,找到单车后需要进行解锁,这时候可以使用QoS level 1质量消息,手机App不断的发送解锁消息给单车锁,确保有一次消息能达到以解锁单车。最后用户用完单车后,需要提交付款表单,可以使用QoS level 2质量消息,这样确保只传递一次数据,否则用户就会多付钱了。
(4)MQTT的消息类型
固定报文头中的第一个字节包含连接标志(Connect Flags),连接标志用来区分MQTT的消息类型。MQTT协议拥有14种不同的消息类型(如表2),可简单分为连接及终止、发布和订阅、QoS2消息的机制以及各种确认ACK。至于每一个消息类型会携带什么内容,这里不多阐述。
(5)遗愿标志(will Flage)
在可变报文头的连接标志位字段(Connect Flags)里有三个Will标志位:Will Flag、Will QoS和Will Retain Flag,这些Will字段用于监控客户端与服务器之间的连接状况。如果设置了Will Flag,就必须设置Will QoS和Will Retain标志位,消息主体中也必须有Will Topic和Will Message字段。
那遗愿消息是怎么回事呢?服务器与客户端通信时,当遇到异常或客户端心跳超时的情况,MQTT服务器会替客户端发布一个Will消息。当然如果服务器收到来自客户端的DISCONNECT消息,则不会触发Will消息的发送。
因此,Will字段可以应用于设备掉线后需要通知用户的场景。
(6)连接保活心跳机制(Keep Alive Timer)
MQTT客户端可以设置一个心跳间隔时间(Keep Alive Timer),表示在每个心跳间隔时间内发送一条消息。如果在这个时间周期内,没有业务数据相关的消息,客户端会发一个PINGREQ消息,相应的,服务器会返回一个PINGRESP消息进行确认。如果服务器在一个半(1.5)心跳间隔时间周期内没有收到来自客户端的消息,就会断开与客户端的连接。心跳间隔时间最大值大约可以设置为18个小时,0值意味着客户端不断开。
(7)异步发布/订阅实现
发布/订阅模式解耦了发布消息的客户(发布者)与订阅消息的客户(订阅者)之间的关系,这意味着发布者和订阅者之间并不需要直接建立联系。
这个模式有以下好处:
①发布者与订阅者只需要知道同一个消息代理即可;
②发布者和订阅者不需要直接交互;
③发布者和订阅者不需要同时在线。
由于采用了发布/订阅实现,MQTT可以双向通信。也就是说MQTT支持服务端反向控制设备,设备可以订阅某个主题,然后发布者对该主题发布消息,设备收到消息后即可进行一系列操作。
三、MQTT协议数据包结构
(1)固定头(Fixed header)
存在于所有MQTT数据包中,表示数据包类型、数据包的分组类标识;
(2)可变头(Variable header)
存在于部分MQTT数据包中,数据包类型决定了可变头是否存在 及具体内容
(3)消息体(Payload)
存在于部分MQTT数据包中,表示客户端收到的具体内容