一文了解MQTT协议
我们之前已经说了这个SSL 和 TCP/IP 协议了,我们今天就来详细的说说这个 MQTT 协议,因为很多消息现在都是支持 MQTT 协议的,比如 RabbitMQ ,还有 Kafka 等,今天我们就来详细的介绍 MQTT 协议到底是个什么。
什么是MQTT协议
MQTT协议是一种消息列队传输协议,采用订阅、发布机制,订阅者只接收自己已经订阅的数据,非订阅数据则不接收,既保证了必要的数据的交换,又避免了无效数据造成的储存与处理。因此在在物联网领域,传感器与服务器的通信,信息的收集中得到广泛的应用。
既然是协议,那么如果对比 TCP/IP协议的话,它位于分层中的哪一层呢?
之前阿粉就说了 TCP/IP 参考模型可以分为四层:应用层、运输层、网络层、网络接口层。TCP和UDP位于运输层,应用层常见的协议有HTTP、FTP、SSH等。而 MQTT 协议运行于 TCP 之上,属于应用层协议,因此只要是支持TCP/IP协议栈的地方,都可以使用MQTT。
MQTT协议主要特性
1)开放消息协议,简单易实现。
2)使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
3)对负载(协议携带的应用数据)内容屏蔽的消息传输。
4)基于TCP/IP网络连接,提供有序,无损,双向连接。
主流的MQTT是基于TCP连接进行数据推送的,但是同样有基于UDP的版本,叫做MQTT-SN。这两种版本由于基于不同的连接方式,优缺点自然也就各有不同了。
5)消息服务质量(QoS)支持,可靠传输保证;有三种消息发布服务质量:
QoS0:"至多一次",消息发布完全依赖底层TCP/IP网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。这一种方式主要普通APP的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就收不到了。
QoS1:"至少一次",确保消息到达,但消息重复可能会发生。
QoS2:"只有一次",确保消息到达一次。在一些要求比较严格的计费系统中,可以使用此级别。在计费系统中,消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送,确保用户收到且只会收到一次。
这个 Qos0 是个什么意思呢?就是如果使用了这个 Qos0 的配置作为发布质量,我们以客户端和服务器为例,那就是客户端发了一个消息给服务端,这时候服务端没有接收到,而配置是 "至多一次",这时候,相同的消息,客户端就不会再继续给服务端发送了,我管你收没收到,我配置的就是最多一次.
同理,QoS1 是至少一次,也就是说,客户端给服务端发送消息的时候,如果没有保证消息到达,这时候可能会继续发送,我才不管我发几次,只要你没有给我说你收到消息,那我就发!
而 QoS2 相对来说就是比较严谨的了,为什么这么说,这就相当于客户端给服务端发送消息,这时候,要求保证客户端发了一次,而服务端收到一次,这样才是相当于只有一次的概念。
6)小型传输,开销很小(固定长度的头部是2字节),协议交换最小化,以降低网络流量。
这就是为什么在介绍里说它非常适合"在物联网领域,传感器与服务器的通信,信息的收集",要知道嵌入式设备的运算能力和带宽都相对薄弱,使用这种协议来传递消息再适合不过了。
MQTT 报文
● 固定报头(fixed header) 所有报文都包含
● 可变报头(variable header) 部分报文包含
● 荷载(payload)部分报文包含
固定报头格式如下
固定报头的0-3位为标志位,第一字节的4-7位的值指定了报文类型。
实际上 这些类型也是 MQTT协议中定义的一些方法(也被称为动作),来于表示对确定资源所进行操作。这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现。通常来说,资源指服务器上的文件或输出。
MQTT协议实现方式
实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:
1)Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容 (payload)
2)payload,可以理解为消息的内容,是指订阅者具体要使用的内容(限制大小)。
MQTT 基于订阅与发布的消息模型
MQTT 消息发送与接收的流程:
● ClientA 链接到 Broker;
● ClientB 链接到 Broker,并订阅主题 Topic1;
● ClientA 发送给 Broker 一条消息,主题为 Topic1;
● Broker 收到 ClientA 的消息,发现 ClientB 订阅了 Topic1,而后将消息转发到 ClientB;
● ClientB 从 Broker 接收到该消息。
和传统的队列有点不一样,若是 ClientB 在 ClientA 发布消息以后再订阅 Topic1,ClientB 不会收到该条消息。
关于 MQTT 的基础,阿粉就了解了这么多了,等以后阿粉学习新的关于 MQTT 的,阿粉再继续分享给大家。
本文转载自公众号Java极客技术