MQTT协议解析 : 物联网领域的最佳选择

1. MQTT协议概述

1.1 MQTT协议是什么

MQTT : Message Queuing Telemetry Transport

  • 模式 : 发布 / 订阅主题
  • 优点 : 代码量小、低带宽、实时可靠
  • 应用 : 物联网、小型设备、移动应用
  • MQTT 常用端口 : 1883

MQTT是一个网络协议,和HTTP类似,因为轻量简单,很多时候传输效率是后者的数十倍。
它仅用极少的代码和有限的带宽,就能为连接远程设备提供实时可靠的消息服务,所以逐渐在物联网(IOT)领域成为了最佳选择。
其实,日常生活中我们也许使用过MQTT,比如你用手机解锁一辆共享单车的时候。

在这里插入图片描述

1.2 MQTT里的角色

MQTT里有3个角色,基于发布 / 订阅模式

  • 代理 Broker (服务器) (消息中转站)
    • 负责接收各个设备发送来的消息,然后把消息转发给需要的设备
  • 发布者 Publisher (客户端)
  • 订阅者 Subscriber (客户端)

可以用视频软件(如抖音/B站)举例子,你(订阅者)关注了某个创作者(发布者),当这个创作者发布新视频的时候,你就会收到B站的推送通知。MQTT协议和上面的简直一模一样。

在这里插入图片描述

2. MQTT协议的工作原理

MQTT协议的消息传输基于客户端-服务器模型,客户端可以是发布者(Publisher)或订阅者(Subscriber),而服务器则负责消息的路由和分发。

2.1 工作流程

  1. 客户端首先与MQTT服务器建立TCP连接,连接成功后,客户端发送一个CONNECT消息,包含客户端标识、用户名、密码等信息。
  2. 服务器验证这些信息后,返回一个CONNACK消息,确认连接。发布者客户端发送PUBLISH消息,将消息发送到特定的主题(Topic),消息包含主题名称、消息有效荷载(Payload)和质量服务等级(QoS)。
  3. MQTT服务器接收到PUBLISH消息后,根据消息的主题,将消息分发给所有订阅了该主题的客户端。这个过程是异步的,确保了消息的高效分发。

在这里插入图片描述

2.2 MQTT底层是TCP/IP

MQTT底层是TCP/IP

  • 连接 : 主动连接服务器,连接的时候带了很多的信息,比如用户名和密码
    • 信息匹配成功后,才会给你响应
  • 发送心跳 & 回应心跳 : 发布者或订阅者发起,服务端响应。
    • 如果长时间没有发送心跳,服务端会认为这个客户端已经离线了,会主动断开连接。
  • 服务质量等级QoS
    • 等级 QoS0 : “最多一次” : 只管发送,不管接收
    • 等级 QoS1 : “最少一次” : 发布以后,服务器必须要回复。如果没收到回复,那么还会继续发,直到你给我回复。
    • 等级 QoS2 : “仅一次” : 发布以后,服务器回复,客户端收到回复以后,发布释放,客户端回复发布完成
      • 应用 : 计费的场景,对次数有严格要求,只要求有一次就够了

除了基于 TCP 的 MQTT,也存在基于 UDP 的 MQTT-SN 等变种协议,不过它们的应用场景和特性与基于 TCP 的 MQTT 有所不同。

3. MQTT数据结构

在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、可变头(Variable header)、消息体 (payload)三部分构成。MQTT数据包结构如下:

在这里插入图片描述

  • 固定头部(Fixed Header) : 这是每个 MQTT 消息都有的部分,长度最小为 2 字节。它包含了消息类型和标志位等信息。
  • 可变头部(Variable Header) : 可选(根据消息类型来判定是否存在)
    • 存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。
  • 有效载荷(Payload) : 可选(根据消息类型来判定是否存在)
    • 存在于部分MQTT数据包中,表示客户端收到的具体内容。

在这里插入图片描述

3.1 固定头部

这是每个 MQTT 消息都有的部分,长度最小为 2 个字节,最多为 5 个字节。

3.1.1 第一个字节

MQTT 协议明确规定高 4 位用于表示消息类型,低 4 位用于表示标志位(如 QoS 级别、保留位、重复位等)。这种定义是基于一种默认的、统一的位顺序来理解的,所有遵循 MQTT 协议的实现都应该按照这个规定的顺序来解析和处理消息。
在这里插入图片描述

3.1.2 第二个字节 - 至多五个字节

第二个字节,高位第一个字节如果为1,表明存在第三个字节,如果为0,表示不存在第三个字节。
在这里插入图片描述

3.2 可变报头

如果是连接请求,可见报头就是下图所示这样。
Byte1-Byte2 是 协议长度。
Byte3-Byte6 是 协议名。
Byte7 是 协议级别。
Byte8 是 连接标志,用来确定是否包含 用户名、密码等。
Byte9-Byte10 用作心跳间隔时间。

在这里插入图片描述

3.3 有效载荷

如果是连接请求,有效载荷就是下图所示这样。
客户端标识符 : 表示你设备的名字,
还有用户名和密码就是放在这里的 (如果有的话)

在这里插入图片描述

4. 抓包

4.1 连接的请求报文

可以看到固定报头、可变报头和有效载荷, Message TypeConnect Command

在这里插入图片描述

4.2 连接的响应报文

没有有效载荷,只有固定报头和可变报头

在这里插入图片描述

4.3 发布的请求报文

Message Type : Publish Message
Topic Length : 主题的长度
Topic : 主题
Message Identifier : 消息ID
Message : 有效载荷,其实解析后就是一个JSON字符串
在这里插入图片描述

4.4 发布的应答报文

在这里插入图片描述

5. 智能家居场景示例

5.1 设备角色介绍

想象一下,你有一个智能家居系统。在这个系统中,有各种各样的设备,就像一个个“小通讯员”。其中包括温度传感器、湿度传感器、智能灯泡和智能窗帘等设备,这些设备就是MQTT中的“客户端(Client)”。

5.2 代理服务器(Broker)的作用

在这个智能家居网络中,还有一个“消息中转站”,也就是MQTT代理(Broker)。它就像是一个社区的收发室,负责接收各个设备发送来的消息,然后把消息转发给需要的设备。

5.3 发布/订阅模式的体现

  • 发布过程:温度传感器就像一个小广播员,它会定期检测室内的温度,然后把温度信息发送(发布)出去。例如,它会把温度数据发布到一个主题(Topic)下,这个主题可以是“home/temperature”。这就好比广播员在广播频道“家庭温度频道”上广播室内温度信息。
  • 订阅过程:智能空调是一个对温度很感兴趣的设备,它会订阅“home/temperature”这个主题。当温度传感器发布了新的温度消息后,代理服务器就会把这个消息转发给智能空调。这就像智能空调一直收听“家庭温度频道”,一旦有新的温度消息广播,它就能收到并根据温度信息来决定是否调整制冷或制热模式。

5.4 不同QoS级别的应用场景

  • QoS 0 - 最多一次传递:智能灯泡的颜色变化信息可以采用QoS 0级别。假设你有一个可以改变颜色的智能灯泡,你通过手机应用设置了一个灯光颜色变化的动态效果。这个颜色变化的消息对于偶尔丢失几条数据不太敏感。如果因为网络问题,有一两条关于颜色变化的指令没有传达到灯泡,可能不会被用户明显察觉,因为灯光效果的连续性不会因为偶尔的丢失而受到严重影响。
  • QoS 1 - 至少一次传递:对于智能窗帘的控制指令可以采用QoS 1级别。比如你发送一个指令让窗帘打开,这个指令比较重要,不能丢失。如果因为网络波动,代理服务器没有收到智能窗帘的确认消息,它会重新发送这个指令,这样就确保了窗帘至少能收到一次打开的指令。即使偶尔收到两次相同的指令,窗帘也只是执行相同的动作(打开),不会产生严重的后果。
  • QoS 2 - 恰好一次传递:在智能家居系统与外部支付系统进行联动的场景下,例如当你购买了一个智能家居服务套餐,支付成功的消息需要以QoS 2级别传递。这个消息必须准确无误地在智能家居系统和支付系统之间传递,既不能丢失也不能重复,以确保你的服务能够正确开通,同时避免因为重复支付而造成损失。

6. MQTT相关工具

  • 调试工具 : MQTTX
  • 抓包工具 :Wireshark
  • 密钥计算工具 : 用于生成用户名和密码加密后的字符串
    • hex_hmac_sha1.js
    • hex_md5.js
    • sign.html

7. 其他

参考

物联网系列 - MQTT协议原理与数据包结构
用B站解释MQTT协议
MQTT协议的工作原理——消息传输
MQTT协议原理与应用精讲
MQTT 协议入门:基础知识和快速教程 | EMQ

MQTT协议测试——MQTT X工具使用_梦的博客-CSDN博客_mqtt测试
推荐八款常用 MQTT 客户端工具 - 知乎 (zhihu.com)
两款常用的 MQTT 调试工具_zuozewei的博客-CSDN博客_mqtt测试工具
MQTT基础 三: 发布、订阅和取消订阅 - 简书 (jianshu.com)

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

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

相关文章

后端Node学习项目-用户管理-增删改查

model层实现 文件创建 在models文件夹下创建user.js 代码实现 const { DataTypes } require(sequelize) const { db } require(./index)const User db.define(user, {id: {type: DataTypes.INTEGER,primaryKey: true, // 主键autoIncrement: true, // 内容自增allowNull…

B+树的介绍

B树的概念 规则: B跟B树不同B树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B树每个非叶子节点所能保存的关键字大大增加 B树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次…

【Rust调用Windows API】获取正在运行的全部进程信息

前言 WIndows API官方文档 提供了C的调用示例,最近想尝试用Rust去实现,本系列博客记录一下实现过程。 依赖 Rust调用Windows API需要引入依赖winapi,在Cargo.toml中添加依赖 winapi "0.3.9"调用不同的API集就需要使用相应的功…

鸿蒙HarmonyOS 网络请求获取数据Http

注意的是;要为接口返回值指定类型 ,以及定义接口数据类型 index.ets import { http } from kit.NetworkKit;interface createAtType {date: number,}interface dataListType {createAt: createAtType;imgUrl: }Component export default struct TabBar {State dat…

2024136读书笔记|《飞鸟集》——使生如夏花之绚烂,死如秋叶之静美

2024136读书笔记|《飞鸟集》——使生如夏花之绚烂,死如秋叶之静美 《飞鸟集》[印]泰戈尔,一本有意思的诗集,中英文对照着读更有意思。“你是谁,读者,百年后读着我的诗?”让我觉得有些久别重逢,忽…

ROS Action

在 ROS 中,Action 是一种支持长时间异步任务的通信机制。与 Service 不同,Action 允许客户端发起一个请求,并在任务执行的过程中不断接收反馈,直到任务完成。这种机制非常适用于可能需要较长时间来完成的任务,比如机器…

C++设计模式和编程框架两种设计元素的比较与相互关系

C设计模式和编程框架都是软件设计中的重要元素,它们各自具有独特的特点和应用场景。以下是对它们的比较,并通过举例说明它们的关系。 C设计模式 定义 设计模式是在软件设计中反复出现的特定问题的解决方案。它们是经过验证的、可复用的设计方案&#…

约束(MYSQL)

not null(非空) unique(唯一) default(默认约束,规定值) 主键约束primary key(非空且唯一) auto_increment(自增类型) 复合主键 check&#xff08…

MySQL 权限困境:从权限丢失到权限重生的完整解决方案20241108

🛠️ MySQL 权限困境:从权限丢失到权限重生的完整解决方案 引言 在使用 MySQL 的过程中,我们常常会遇到权限设置不当或丢失的问题,特别是在初次安装或配置更改后。这种权限困境的修复不仅复杂,而且往往是环环相扣&…

笔记 | image may have poor performance,or fail,if run via emulation

在Docker Desktop中现象如图: 当你运行 AMD64 平台代码时(Intel 和 AMD 芯),你的 Mac 必须模拟其CPU架构(因为你自身是ARM)。这通常会非常吃性能。 Docker Desktop 警告你在模拟 Intel/AMD x64 CPU 时性能可…

【C++】C++11特性(上)

✨✨欢迎大家来到Celia的博客✨✨ 🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉 所属专栏:C 个人主页:Celias blog~ 目录 一、列表初始化 二、std::initializer_list 三、右值引用和移…

【WebRTC】视频发送链路中类的简单分析(下)

目录 1.任务队列节流发送器(TaskQueuePacedSender)1.1 节流控制器添加RTP数据包(PacingController::EnqueuePacket())1.2 监测是否要处理Packet(PacingController::MaybeProcessPackets()) 2.数据包路由&am…

24/11/7 算法笔记 PCA主成分分析

假如我们的数据集是n维的,共有m个数据(x,x,...,x)。我们希望将这m个数据的维度从n维降到k维,希望这m个k维的数据集尽可能的代表原始数据集。我们知道数据从n维降到k维肯定会有损失,但是我们希望损失尽可能的小。那么如何让这k维的数据尽可能表…

JS 实现SSE通讯和了解SSE通讯

SSE 介绍: Server-Sent Events(SSE)是一种用于实现服务器向客户端实时推送数据的Web技术。与传统的轮询和长轮询相比,SSE提供了更高效和实时的数据推送机制。 SSE基于HTTP协议,允许服务器将数据以事件流(…

C/C++每日一练:查找链表的中间节点

链表(Linked List) 链表是一种线性数据结构,由一系列节点(Node)通过指针链接在一起。与数组不同,链表中的元素在内存中不需要连续存储,每个节点包含两部分: 数据部分:存…

对称加密与非对称加密:密码学的基石及 RSA 算法详解

对称加密与非对称加密:密码学的基石及 RSA 算法详解 在当今数字化的时代,信息安全至关重要。对称加密和非对称加密作为密码学中的两种基本加密技术,为我们的数据安全提供了强大的保障。本文将深入探讨对称加密和非对称加密的特点、应用场景&…

PH47代码框架全局函数及功能类

PH47代码框架全局函数及功能类 概述 全局函数及功能类体系是PH47框架当中除了4个逻辑层之外最重要的组成部分之一,它们可以在 整个PH7 代码框架及用户代码中使用。常用全局函数及功能类为 PH7 代码框架提供了最常用和最基础的功能实现。 全局函数主要包含了对时间…

Spark 中的 RDD 分区的设定规则与高阶函数、Lambda 表达式详解

Spark 的介绍与搭建:从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交:本地与集群模式全解析-CSDN博客 Spark on YARN:Spark集群模式…

Spring学习笔记_30——事务接口PlatformTransactionManager

PlatformTransactionManager是Spring框架中事务管理的核心接口,它负责管理事务的创建、提交和回滚等操作。 源码 /** Copyright 2002-2020 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you m…

力扣 LeetCode 203. 移除链表元素(Day2:链表)

解题思路: 方法一:头节点和非头节点分开处理 方法二:定义一个dummy虚拟节点,后面的节点就可以采用相同的处理方式 注意: cur需要指向要删除的节点的上一个节点,因为要越过这一个被删除的节点 class Sol…