文章大纲

  • 引言
  • 一、MQTT 协议
  • 1、MQTT协议概述
  • 2、MQTT的主要特点
  • 3、MQTT 设计原则
  • 二、MQTT 协议核心角色
  • 1、 MQTT客户端
  • 2、 MQTT服务器
  • 三、MQTT 主要工作流程和服务质量QoS
  • 1、MQTT 通信核心流程
  • 2、MQTT 消息发布的三种服务质量(`QoS`)
  • 2.1、`QoS 0:At most once(deliver and forget)`至多分发一次
  • 2.2、`QoS 1 :At least once`至少分发一次
  • 2.3、`QoS 2 :Exactly once`只有一次


引言

在AIoT 如此流行的今天,未来智能家居、智能车联网、智能物联网必将有广阔的天空,而MQTT 作为一种专门为物联网设计的协议,接下来文章就好好总结相关理论知识。

一、MQTT 协议

本文档基于 MQTT 协议版本v3.1.1,部分理论摘自MQTT中文网,其他见图片水印。

1、MQTT协议概述

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)广泛应用于机器对机器(M2M)/物联网(IoT)的应用层连接协议,使用极其轻量级的发布/订阅二进制消息模型通信。对于需要较小代码占用空间和或网络带宽非常宝贵的远程连接非常有用,是专为受限设备(电池功率非常高的移动应用设备)和低带宽、高延迟或不可靠的环境通信而设计的。不仅为新兴的“机器到机器”(M2M)或物联网(IoT)世界提供连接,还被用于通过卫星链路与代理通信的传感器、与医疗服务提供者的拨号连接以及一系列家庭自动化和小型设备场景。

主流的MQTT是基于TCP连接进行数据推送的,但是同样有基于UDP的版本,叫做MQTT-SN

MQTT java简单demo_网络协议

2、MQTT的主要特点

MQTT协议工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:

  • 底层基于TCP/IP (或者UDP) 协议传输,采用发布/订阅模式的二进制消息模式,提供一对多的消息发布
  • 控制包结构精简,第一个 1字节固定报头,第二个2字节心跳报文,最小化传输开销和协议交换,有效减少网络流量。
  • 消息QoS支持,可靠传输保证
  • 使用Last Will和Testament特性通知有关各方客户端异常中断的机制。

Last Will即遗言机制,用于通知同一主题下的其他设备发送遗言的设备已经断开了连接;而Testament遗嘱机制,功能类似于Last Will。

3、MQTT 设计原则

由于物联网的环境是非常特别的,所以MQTT遵循以下设计原则:

  • 精简,不添加可有可无的功能,理解客户端计算能力可能很低
  • 发布/订阅(Pub/Sub)模式,方便消息在传感器之间传递;
  • 允许用户动态创建主题,零运维成本;
  • 把传输量降到最低以提高传输效率,支持低带宽、高延迟、不稳定的网络等因素考虑在内;
  • 支持连续的会话控制;
  • 提供服务质量管理;
  • 假设数据不可知,不强求传输数据的类型与格式,保持灵活性。

二、MQTT 协议核心角色

MQTT 协议主要有三大核心角色:发布者(Publisher)、Broker代理服务器(转发者)订阅者(Subscriber)。其中消息的发布者和订阅者都是客户端角色,消息代理是服务器,消息发布者可以同时是订阅者。

1、 MQTT客户端

MQTT客户端身兼二职:既可以是发布者角色,又可以是订阅者角色。一个使用MQTT协议的应用程序或者设备就是一个MQTT 客户端,工作时它需要主动去连接到代理服务器,所以MQTT客户端的功能有:

  • 主动与Broker 建立连接,主动断开Broker的连接
  • 作为发布者角色,发布给其他客户端订阅的Topic
  • 作为订阅者,主动订阅其它客户端发布的Topic
  • 退订之前订阅的Topic
  • 清空服务端之前保留的Message

2、 MQTT服务器

MQTT通信必须依赖一个MQTT Broker,Broker(服务器)可以看出是MQTT网络的Hub,负责处理客户端的订阅逻辑并转发给其他订阅的客户端,如下图所示。

MQTT java简单demo_mqtt_02

MQTT服务器又称为"消息代理"服务器(Broker),可以是一个应用程序或一台设备,它是位于消息发布者和订阅者之间,具有以下功能:

  • 接受来自客户端的网络连接并建立通信链路
  • 接收发布者的Topic并转发给订阅者
  • 处理来自客户端的订阅和退订请求
  • 向订阅的客户转发相应地Topic

三、MQTT 主要工作流程和服务质量QoS

MQTT java简单demo_mqtt_03

1、MQTT 通信核心流程

如图https://blog.p2hp.com/archives/4100所示,MQTT 的工作流程十分便捷,MQTT 客户端之间的通信都是需要通过Broker 间接实现,两个客户端想要通信,它们必须具备以下前提:

  • 两个MQTT 客户端成功与同一个Broker 建立连接
  • 两个MQTT 客户端之间约定一个相同的Topic(不一定完全相同,可以用通配符“+”替代)

发布者和订阅者在成功和同一个Broker 建立连接后,发布者向Broker 发布一个Topic,Broker 转发给订阅了这个Topic 的所有订阅者。

2、MQTT 消息发布的三种服务质量(QoS

MQTT java简单demo_mqtt_04

2.1、QoS 0:At most once(deliver and forget)至多分发一次

“至多一次”,消息发布完全依赖底层TCP/IP网络可能会发生消息丢失或重复,接收者不发送响应,发送者也不重新尝试。接收者只能收到一次消息或者一次也收不到。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。这一种方式主要普通APP的推送,倘若你的智能设备在消息推送时未联网,推送过去没收到,再次联网也就收不到了。

MQTT java简单demo_MQTT java简单demo_05

2.2、QoS 1 :At least once至少分发一次

确保消息到达,但消息重复可能会发生。可以确保消息至少一次抵达接收者。QoS 1的PUBLISH包的可变包头包含包唯一标识,而且有PUBACK包确认。在QoS 1的分发协议中,发送者

  • 每次发布新的应用消息,必须分配一个没有用过的包唯一标识。
  • 包含唯一标识的PUBLISH包也必须是QoS=1,DUP=0。
  • 必须把PUBLISH包当作“未确认的”,直到从接收者那里收到对应的PUBACK包。

一旦发送者收到PUBACK包,包唯一标识就可以重用了。而在QoS 1的分发协议中,接收者

  • 必须响应一个包含与PUBLISH包相同的包唯一标识,来接受应用消息的所属关系。
  • 在发送PUBACK包之后,接收者必须把所有收到的包含相同包唯一标识的PUBLISH包当作一个新的发布,无论是否设置了DUP标识。

MQTT java简单demo_网络协议_06

2.3、QoS 2 :Exactly once只有一次

最高的服务质量,用在丢失和重复消息都不能被接受的情况确保消息到达一次。在一些要求比较严格的计费系统中,可以使用此级别。在计费系统中,消息重复或丢失会导致不正确的结果。这种最高质量的消息发布服务还可以用于即时通讯类的APP的推送,确保用户收到且只会收到一次。QoS 2消息的可变包头包含包唯一标识,QoS 2的PUBLISH包的接收者分两步确认接收,在QoS 2的分发协议中,发送者

  • 每次发布新的应用消息,必须分配一个没有用过的包唯一标识。
  • 包含唯一标识的PUBLISH包也必须是QoS=1,DUP=0。
  • 必须把PUBLISH包当作“未确认的”,直到从接收者那里收到对应的PUBACK包。
  • 当从接收者那里收到PUBREC包时要发送PUBREL包。PUBREL包必须包含与原始PUBLISH包相同的包唯一标识。
  • 必须把PUBREL包当作“未确认的”,直到从接收者那里收到对应的PUBCOMP包。
  • 一旦已经发送了相应的PUBREL包,就不能再重发PUBLISH包。

当发送者收到PUBCOMP包之后,包唯一标识就可以重用了。在QoS 2的分发协议中,接收者

  • 必须响应一个包含与PUBLISH包相同的包唯一标识,来接受应用消息的所属关系。
  • 直到收到相应的PUBREL包,接收者必须发送包含相同包唯一标识的PUBREC来确认后来的PUBLISH包。这样一定不会导致重复的消息被分发到接下来的接收者。
  • 必须用包含相同包唯一标识的PUBCOMP包来响应一个PUBREL包。
  • 在发送PUBCOMP之后,接收者必须把所有收到的包含相同包唯一标识的PUBLISH包当作一个新的发布。

MQTT java简单demo_MQTT java简单demo_07


未完待续…