MQTT 协议概述

news2024/11/18 5:58:14

目录

  • 一、概述
  • 二、协议模型
    • 1、组成部分
    • 2、客户端
    • 3、服务器
  • 三、MATT 通信过程
    • 1、连接服务器
    • 2、订阅主题
    • 3、发布消息
    • 4、取消订阅
    • 5、断开连接
  • 四、MQTT 数据包结构
    • 1、MQTT 固定头
    • 2、MQTT 可变头
    • 3. Payload消息体
  • 五、示例演示


一、概述

MQTTMessage Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于 TCP/IP 协议上,由 IBM 在 1999 年发布,并于 2013 年发布为开放标准。MQTT 协议专注于在低带宽、不稳定或高延迟的网络环境中,可靠地传输小型数据包。

MQTT协议具有以下特点:

  • 轻量级:MQTT 的协议开销小,适用于资源受限的设备,如传感器、物联网设备等。
  • 灵活和可扩展:MQTT 支持多种传输层协议,如 TCP/IPWebSocket 等。它还提供了 QoS(Quality of Service)级别,以确保消息的可靠传输。
  • 异步通信:MQTT 使用发布/订阅模型,发布者和订阅者之间不需要直接通信,使得系统的解耦更容易。
  • 处理低带宽和高延迟网络:MQTT 协议可以在网络连接不稳定或带宽有限的环境中可靠地传输数据。

二、协议模型

1、组成部分

MQTT 协议基于 TCP/IP 协议,通常在应用层上使用,通过客户端和服务端之间的发布/订阅模型进行通信。它有以下几个主要组成部分:

  • Broker(代理服务器):是 MQTT 网络中的中间件,负责接收来自客户端的消息,并将消息路由到符合订阅条件的客户端。Broker 还负责维护客户端的连接状态。
  • Publisher(发布者):是发送消息的 MQTT 客户端。发布者将消息发送到 Broker,并指定一个或多个主题(Topic)。
  • Subscriber(订阅者):是接收消息的 MQTT 客户端。订阅者通过向 Broker 订阅一个或多个主题,以接收与这些主题相关的消息。
  • Topic(主题):是消息的类别或标签,用于将发布者的消息与订阅者的接收行为关联起来。主题由一个或多个层级组成,可以使用通配符进行匹配。

2、客户端

MQTT 客户端可以是发布者或订阅者,用于发送或接收消息。MQTT 客户端可以运行在各种设备上,如传感器、嵌入式设备、服务器等。它们通过与 MQTT 服务端建立连接进行通信。

MQTT 客户端具有如下功能:

  • 发布消息给其它相关的客户端。
  • 订阅主题请求接收相关的应用消息。
  • 取消订阅主题请求移除接收应用消息。
  • 从服务端终止连接。

3、服务器

MQTT 服务器负责接收来自客户端的消息,并将消息路由到符合订阅条件的客户端。它还负责维护客户端的连接状态。MQTT 服务器通常运行在一个可靠的服务器上,并提供消息的持久化存储、安全认证、订阅管理等功能。

MQTT 服务器具有如下功能:

  • 接受来自客户端的网络连接请求。
  • 接受客户端发布的应用消息。
  • 处理客户端的订阅和取消订阅请求。
  • 转发应用消息给符合条件的已订阅客户端(包括发布者自身)。

三、MATT 通信过程

MQTT 使用的发布/订阅消息模式,它提供了一对多的消息分发机制,从而实现与应用程序的解耦。这是一种消息传递模式,消息不是直接从发送器发送到接收器(即点对点),而是由 MQTT Broker 分发的。

1、连接服务器

客户端到服务器的网络连接建立后,客户端发送给服务器的第一个报文必须是 CONNECT 报文

在一个网络连接上,客户端只能发送一次 CONNECT 报文,如果出现第二个 CONNECT 报文,按照协议标准,服务器会将第二个CONNECT 报文当作协议违规处理并断开客户端的连接。

对于正常的连接请求,服务器必须产生应答报文,如果无法建立会话,服务器应该在应答报文中报告对应的错误代码。

2、订阅主题

MQTT 客户端可以订阅一个或多个主题,以接收与这些主题相关的消息。订阅的客户端被称为订阅者。

订阅消息的过程如下:

  • 客户端与 MQTT 服务端建立连接。
  • 客户端使用指定的主题进行订阅。
  • MQTT 服务端将订阅信息保存,并等待有与所订阅主题相关的消息到达。
  • 当有新的消息发布到与订阅主题匹配的主题上时,MQTT 服务端将消息路由给订阅者。
  • 订阅者接收到消息,并进行相应的处理。

MQTT 中,主题(Topic)扮演着重要的角色。主题是一个用于标识消息类型或内容的字符串,如"weather/temperature"、"home/lights"等。订阅者可以通过使用通配符进行模糊匹配来订阅多个相关主题,如"weather/+"表示订阅以"weather/“开头的所有主题,”+"代表一个层级的通配符。

SUBSCRIBE 为每个订阅指定了最大的 QoS 等级,服务器根据这些信息分发应用消息给客户端。

SUBSCRIBE 报文拥有固定报头、可变报头、有效载荷。

当服务器收到客户端发送的一个 SUBSCRIBE 报文时,必须向客户端发送一个 SUBACK 报文响应,同时 SUBACK 报文必须和等待确认的SUBSCRIBE 报文有相同的报文标识符。

如果服务器收到一个 SUBSCRIBE 报文,报文的主题过滤器与一个现存订阅的主题过滤器相同,那么必须使用新的订阅彻底替换现存的订阅。新订阅的主题过滤器和之前订阅的相同,但是它的最大 QoS 值可以不同。与这个主题过滤器匹配的任何现存的保留消息必须被重发,但是发布流程不能中断。

3、发布消息

MQTT 客户端可以发布消息到 MQTT 服务端(当然,从服务器分发的报文给订阅者,也是属于 PUBLISH 控制报文。),通过指定一个或多个主题来标识消息的类型或内容。发布的消息可以是任意格式的数据,如文本、二进制数据等。发布消息的客户端被称为发布者(Publisher)。

发布消息的过程如下:

  • 客户端与 MQTT 服务端建立连接。
  • 客户端使用指定的主题和内容发布消息。
  • MQTT 服务端接收到消息后,将消息路由给符合订阅条件的订阅者(Subscriber)。
  • 订阅者接收到与其订阅主题相关的消息。

这里了解一个概念:QoSQuality of Service levels,服务质量):

服务质量是 MQTT 的一个重要特性。当我们使用 TCP/IP 时,连接已经在一定程度上受到保护。但是在无线网络中,中断和干扰很频繁,MQTT 在这里帮助避免信息丢失及其服务质量水平。这些级别在发布时使用。

  • 如果客户端发布到 MQTT 服务器,则客户端将是发送者,MQTT 服务器将是接收者。
  • MQTT 服务器向客户端发布消息时,服务器是发送者,客户端是接收者。

QoS 有三个等级:

  1. QoS 0:这一级别会发生消息丢失或重复,消息发布依赖于底层TCP/IP网络。即:<=1

在这里插入图片描述

  1. QoS 1:QoS 1 承诺消息将至少传送一次给订阅者。

在这里插入图片描述

  1. QoS 2:使用 QoS 2,我们保证消息仅传送到目的地一次。为此,带有唯一消息 ID 的消息会存储两次,首先来自发送者,然后是接收者。QoS 级别 2 在网络中具有最高的开销,因为在发送方和接收方之间需要两个流。

4、取消订阅

客户端发送 UNSUBSCRIBE 报文给服务器,用于取消订阅主题。

UNSUBSCRIBE 报文固定报头的第 3,2,1,0 位是保留位且必须分别设置为 0,0,1,0。否则服务器必须认为任何其它的值都是不合法的并关闭网络连。具体的描述可以看协议文档。

UNSUBSCRIBE 报文的有效载荷包含客户端想要取消订阅的主题过滤器列表。UNSUBSCRIBE 报文中的主题过滤器必须是连续打包的 UTF-8 编码字符串。

UNSUBSCRIBE 报文的有效载荷必须至少包含一个主题过滤器列表,而且这个主题过滤器是已经被客户端订阅的,否则的话没有订阅也就没有取消订阅一说了。如果一个 UNSUBSCRIBE 报文没有有效载荷是违反协议的标准的,服务器也不会去处理它。

而对于服务器删除了一个订阅,那么它将不会再分发该主题的消息到这个客户端中。而且它必须完成分发任何已经开始往客户端发送的QoS1QoS2 的消息,以保证消息的服务质量。

然后服务器必须发送 UNSUBACK 报文来响应客户端的 UNSUBSCRIBE 请求。UNSUBACK 报文必须包含和 UNSUBSCRIBE 报文相同的报文标识符。即使没有删除任何主题订阅(客户端取消订阅的主题未被订阅),服务器也必须发送一个 UNSUBACK 响应。

5、断开连接

DISCONNECT 报文是客户端发给服务端的最后一个控制报文。表示客户端正常断开连接。

DISCONNECT 报文的固定报头保留位必须全为 0。

客户端发送 DISCONNECT 报文之后必须关闭网络连接,不能通过那个网络连接再发送任何控制报文。

服务端在收到 DISCONNECT 报文时必须丢弃任何与当前连接关联的未发布的遗嘱消息。而且当客户端没有关闭网络连接的时候服务器应该主动去关闭网络连接。

四、MQTT 数据包结构

  • 固定头(Fixed header),存在于所有 MQTT 数据包中,表示数据包类型及数据包的分组类标识;
  • 可变头(Variable header),存在于部分 MQTT 数据包中,数据包类型决定了可变头是否存在及其具体内容;
  • 消息体(Payload),存在于部分 MQTT 数据包中,表示客户端收到的具体内容;

整体 MQTT 的消息格式如下图所示;

1、MQTT 固定头

固定头存在于所有 MQTT 数据包中,其结构如下:

其中,MQTT 消息类型是一个 4 位的无符号值,类型如下:

名称流方向描述
Reserved0不可用保留位
CONNECT1客户端到服务器客户端请求连接到服务器
CONNACK2服务器到客户端连接确认
PUBLISH3双向发布消息
PUBACK4双向发布确认
PUBREC5双向发布收到(保证第1部分到达)
PUBREL6双向发布释放(保证第2部分到达)
PUBCOMP7双向发布完成(保证第3部分到达)
SUBSCRIBE8客户端到服务器客户端请求订阅
SUBACK9服务器到客户端订阅确认
UNSUBSCRIBE10客户端到服务器请求取消订阅
UNSUBACK11服务器到客户端取消订阅确认
PINGREQ12客户端到服务器PING请求
PINGRESP13服务器到客户端PING应答
DISCONNECT14客户端到服务器中断连接
Reserved15不可用保留位

标识位(DUP):在不使用标识位的消息类型中,标识位被作为保留位。如果收到无效的标志时,接收端必须关闭网络连接:

数据包标识位Bit 3Bit 2Bit 1Bit 0
CONNECT保留位0000
CONNACK保留位0000
PUBLISHMQTT 3.1.1 使用DUP1QoS2QoS2RETAIN3
PUBACK保留位0000
PUBREC保留位0000
PUBREL保留位0000
PUBCOMP保留位0000
SUBSCRIBE保留位0000
SUBACK保留位0000
UNSUBSCRIBE保留位0000
UNSUBACK保留位0000
PINGREQ保留位0000
PINGRESP保留位0000
DISCONNECT保留位0000

QoS:发布消息的服务质量(前面已经做过介绍),即:保证消息传递的次数
- 00:最多一次,即:<=1
- 01:至少一次,即:>=1
- 10:一次,即:=1
- 11:预留

RETAIN:发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果设有那么推送至当前订阅者后释放。

2、MQTT 可变头

MQTT 数据包中包含一个可变头,它驻位于固定的头和负载之间。可变头的内容因数据包类型而不同,较常的应用是做为包的标识:

Bit7 — 0
byte 1包标签符(MSB)
byte 2…包标签符(LSB)

很多类型数据包中都包括一个 2 字节的数据包标识字段,这些类型的包有:PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK2.3。

3. Payload消息体

Payload 消息体是 MQTT 数据包的第三部分,有 CONNECTSUBSCRIBESUBACKUNSUBSCRIBE 四种类型的消息:

  • CONNECT,消息体内容主要是:客户端的 ClientID、订阅的 Topic、Message 以及用户名和密码
  • SUBSCRIBE,消息体内容是一系列的要订阅的主题以及 QoS。
  • SUBACK,消息体内容是服务器对于 SUBSCRIBE 所申请的主题及 QoS 进行确认和回复。
  • UNSUBSCRIBE,消息体内容是要订阅的主题。

五、示例演示

上文简单讲了一下 MQTT 协议,下面借助 MQTTXMQTT.FX 工具来演示一下 MQTT 的工作。

首先在 MQTTX 上新建一个服务器,这里的地址就使用工具免费的测试地址就可以。为了简便,这里就不设置用户密码了。

然后在 MQTT.FX 配置好客户端:

连接成功:

然后订阅主题:

可以看到,当服务器发布一个消息的时候,客户端收到了相应的消息:


同理,现在让服务器订阅客户端的主题:

服务器也能收到相应的消息:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2133156.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

乔拓云模板助力,微信小程序快速上线无需愁备案

想要快速打造并上线自己的微信小程序吗&#xff1f;乔拓云平台是您的不二之选&#xff01;无需担心复杂的备案流程&#xff0c;乔拓云提供免费服务&#xff0c;远程协助您轻松完成微信小程序的备案工作。 只需简单几步&#xff0c;您的小程序就能闪亮登场&#xff1a;首先&…

常见加密算法——哈希算法(MD)

文章目录 发现宝藏1.加密算法简介1.1 加密算法分类1.2 应用场景1.3 哈希算法的特点 2. 哈希算法的分类2.1 加密哈希算法2.2 非加密哈希算法2.3 其他常见哈希算法 3. MD53.1 MD5 简介3.2 MD5 Java 代码示例&#xff08;未加盐&#xff09;3.2 MD5 Python 代码示例&#xff08;未…

DroidBot: A Lightweight UI-Guided Test InputGenerator for Android论文学习

DroidBot就是之前用过的那个自动截图程序。那我很熟悉了&#xff0c;快速读完这篇论文。 brain默认使用深度优先探索&#xff0c;当然用户也可以使用自己的方法。 这玩意支持各种输入&#xff08;点击&#xff0c;滑动&#xff0c;输入文本&#xff09; 可以看到它会分辨当前页…

【Linux】探索进程控制奥秘,解锁高效实战技巧

目录 1.进程创建 1.1字符串常量为什么不可以修改&#xff1f; 1.2代码段和数据段到底是什么&#xff1f; 1.3.fork函数初识 1.4.fork函数返回值 1.5.写时拷贝&#xff1a; 1.6写时拷贝按需进行的原理&#xff08;与页表的权限有关&#xff09; 1.7.fork常规用法 2.进程…

跟着iMeta学做图 | 冲击图展示菌群随盐度的变化

本文代码已经上传至https://github.com/iMetaScience/iMetaPlot如果你使用本代码&#xff0c;请引用&#xff1a;Changchao Li. 2023. Destabilized microbial networks with distinct performances of abundant and rare biospheres in maintaining networks under increasing…

gen_server补充基础学习

学习gen_server的回调结构 gen_server:start_link(Name, Mod, InitArgs, Opts)这个调用是所有事物的起点。它 会创建一个名为Name的通用服务器&#xff0c;回调模块是Mod&#xff0c;Opts则控制通用服务器的行为。在这里可以指定消息记录、函数调试和其他行为。通用服务器通过…

基于QGIS 3.16.0 的OSM路网矢量范围裁剪实战-以湖南省为例

目录 前言 一、相关数据介绍 1、OMS路网数据 2、路网数据 3、路网图层属性 二、按省域范围进行路网裁剪 1、裁剪范围制定 2、空间裁剪 3、裁剪结果 三、总结 前言 改革开放特别是党的十八大以来&#xff0c;我国公路发展取得了举世瞩目的成就。国家高速公路网由“7 射…

ATECLOUD平台相比传统ATE测试有哪些独特的优势?

随着科技的飞速发展&#xff0c;在电子测量行业&#xff0c;自动化测试也逐渐取代了传统手动&#xff0c;市场上的大多数测试企业近几年都在进行自动化转型&#xff0c;而伴随着测试行业自动化、智能化的趋势&#xff0c;各类自动化测试系统也发展迅速&#xff0c;在众多ATE自动…

一种模式包含引流和复购 让你的私域电商平台腾飞!

在当今的商业环境中&#xff0c;一种名为“循环购”的创新商业模式正悄然兴起&#xff0c;它打破了传统消费观念&#xff0c;让“消费1000送2000&#xff0c;每日领钱&#xff0c;轻松提现”不再是遥不可及的梦想。很多人可能会问&#xff0c;这究竟是商家的慷慨解囊&#xff0…

多模态大模型-MiniCPM-V

1. 简介 本文主要探索如何在性能和效果之间的权衡&#xff0c;希望能在合适的性能下&#xff0c;模型效果有大幅的提升。主要贡献点有&#xff1a; 通过模型结构&#xff0c;数据&#xff0c;训练策略等优化&#xff0c;让MiniCPM-Lllama3-V 2.5[1]在OpenCompass评测上超过了…

03:手动可变电阻

可变电阻 1、电位器2、变阻器/数字电位器2.1&#xff1a;变阻器2.2&#xff1a;数字电位器 3、电位器锥度4、寄生电感/电容 1、电位器 如上图所示&#xff1a;将可变的电阻作为分压器&#xff0c;那么这种可变的电阻就是电位器。例如&#xff1a;将L1连接负极&#xff0c;L3连接…

SQLMAP windows10 安装记录

1.Windows系统下安装Sqlmap&#xff0c;需要安装python环境 python下载和安装 官方下载 https://www.python.org/downloads 建议直接下载安装版&#xff1a;installer 最后到这个界面正常是成功了&#xff0c;但也要校验一下 进入windows 命令窗口 正常输入你安装的python 版本…

OpenHarmony(鸿蒙南向开发)——轻量系统芯片移植指南(二)

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ OpenHarmony&#xff08;鸿蒙南向开发&#xff09;——轻量系统芯片移植指南(一) Op…

数据库与表的操作

目录 1. 库的操作 1.1创建数据库案例 1.2字符集和校验规则 1.2.1查看系统默认字符集以及校验规则 1.2.2 查看数据库支持的字符集 1.2.3查看数据库支持的字符集校验规则 1.2.4校验规则对数据库的影响 1.3.1查看数据库 1.3.2显示创建语句 1.3.3修改数据库 1.3.4 数据…

将一句英文颠倒输出

例如&#xff1a; 输入&#xff1a;s “i am from beijing" 输出&#xff1a;”beijing form am i“ #include <stdio.h> #include <string.h>//i am form nanjing //ginjnan mrof ma i //nanjing form am i//逆序算法(首尾互换) void Reserve(char *s,in…

windows 创建新用户,并分配到指定组

右击电脑 -> 点击管理 在右边右击&#xff0c;选择新用户&#xff0c;输入相关信息创建 创建用户后&#xff0c;选择用户&#xff0c;右击&#xff0c;选择属性&#xff0c;添加 点击高级 点击立即查找&#xff0c;可以搜索出所有可用的组&#xff0c;为其选择即可

mosh java 2.4 inheritance继承

1.面向对象编程的第三个特点 继承 继承的好处 java不能继承多个父级 代码文件结构 1.main.java package org.example; //package org.codewithme;//import org.example.UIControl;//TIP To <b>Run</b> code, press <shortcut actionId"Run"/> or /…

《深度学习》PyTorch 手写数字识别 案例解析及实现 <上>

目录 一、了解MINIST数据集 1、什么是MINIST 2、查看MINIST由来 二、实操代码 1、下载训练数据集 2、下载测试数据集 运行结果&#xff1a; 3、展示手写数字图片 运行结果&#xff1a; 4、打包图片 运行结果&#xff1a; 5、判断当前pytorch使用的设备 1&#xff…

RK3568 外接摄像头预览方向错误

1.测试发现摄像头预览方向被旋转了90度 2.问题原因: device\rockchip\common\external_camera_config.xml 配置文件旋转了90度: 3.解决对策 修改orientation为0度

MultiSnapRecyclerView:让Android RecyclerView的滚动停靠更灵活

在Android应用开发中&#xff0c;RecyclerView是一个强大且灵活的组件&#xff0c;用于展示大量数据集合。然而&#xff0c;标准的RecyclerView只支持单一的滚动停靠点&#xff0c;这在某些场景下可能不够灵活。为了解决这个问题&#xff0c;TakuSemba开发了一个名为MultiSnapR…