imx6ull/linux应用编程学习(14) MQTT基础知识

news2024/9/21 12:24:16

什么是mqtt?

        与HTTP 协议一样, MQTT 协议也是应用层协议工作在 TCP/IP 四层模型中的最上层(应用层)构建于 TCP/IP协议上。 MQTT 最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用

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

①、 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。

②、基于 TCP/IP 提供网络连接。

        主流的 MQTT 是基于 TCP 连接进行数据推送的,但是同样也有基于 UDP 的版本,叫做 MQTT-SN。这两种版本由于基于不同的连接方式,优缺点自然也就各有不同了。

③、支持 QoS 服务质量等级。

根据消息的重要性不同设置不同的服务质量等级。

④、 小型传输, 开销很小,协议交换最小化,以降低网络流量。

        这就是为什么在介绍里说它非常适合"在物联网领域,传感器与服务器的通信,信息的收集",要知道嵌入式设备的运算能力和带宽都相对薄弱,使用这种协议来传递消息再适合不过了, 在手机移动应用方面, MQTT 是一种不错的 Android 消息推送方案。

⑤、使用 will 遗嘱机制来通知客户端异常断线。

⑥、基于主题发布/订阅消息,对负载内容屏蔽的消息传输。

⑦、支持心跳机制。

MQTT 通信基本原理

服务端和客户端


        MQTT 是一种基于客户端-服务端架构的消息传输协议,所以在 MQTT 协议通信中,有两个最为重要的角色,它们便是服务端和客户端

MQTT 主题

        客户端想要从服务器获取信息,首先需要订阅信息,"主题”在 MQTT 通信中是一个非常重要的概念,客户端发布信息以及订阅信息都是围绕“主题”来进行的。

        客户端发布消息时需要为消息指定一个“主题”, 表示将消息发布到该主题;而对于订阅消息的客户端来说,可通过订阅“主题” 来订阅消息,这样当其它客户端或自己(当前客户端)向该主题发布消息时, MQTT 服务端就会将该主题的信息发送给该主题的订阅者(客户端)。

        在以上图示中一共有三个 MQTT 客户端, 它们分别是开发板、 手机和电脑。 MQTT 服务端在管理 MQTT通信时使用了“主题”来对信息进行管理。比如上图所示,假设我们需要利用手机和电脑获取开发板在运行过程中 SoC 芯片的温度,那么首先电脑和手机这两个客户端需要向 MQTT 服务器订阅主题“芯片温度” ;接下来,当开发板客户端向服务端的“芯片温度”主题发布信息(假设信息的内容就是当前的温度值) 后服务端就会首先检查都有哪些客户端订阅了“芯片温度”这一主题的信息,而当它发现订阅了该主题的客户端有一个手机和一个电脑,于是服务端就会将刚刚收到的“芯片温度”信息转发给订阅了该主题的手机和电脑客户端。

        以上实例中, 开发板是“芯片温度”主题的发布者,而手机和电脑则是该主题的订阅者。

值得注意的是, MQTT 客户端在通信时,角色往往不是单一的, 一个客户端既可以作为信息发布者也可以同时作为信息订阅者。如下图所示:

        图中的所有客户端都是围绕“LED 控制”这一主题进行通信。此时,对于“LED 控制”这一主题来说,手机和电脑客户端成为了 MQTT 信息的发布者而开发板则成为了 MQTT 信息的订阅者(接收者)。

MQTT 发布/订阅特性
 

客户端相互独立
        MQTT 客户端是一个个独立的个体, 它们无需了解彼此的存在,依然可以实现信息交流。

空间上分离

        MQTT 客户端以及 MQTT 服务端它们在通信时是处于同一个通信网络中的, 这个网络可以是互联网或者局域网; 只要客户端联网,无论他们远在天边还是近在眼前,都可以实现彼此间的通讯交流;其实网络通信本就是如此,所以并不是 MQTT 通信所特有的。

时间上可异步
        MQTT 客户端在发送和接收信息时无需同步。这一特点对物联网设备尤为重要

连接 MQTT 服务端

        MQTT 客户端连接服务端总共包含了两个步骤:

        ①、首先客户端需要向服务端发送连接请求,这个连接请求实际上就是向服务端发送一个 CONNECT报文,也就是发送了一个 CONNECT 数据包。

        ②、 MQTT 服务端收到连接请求后,会向客户端发送连接确认。 连接确认实际上是向客户端发送一个CONNACK 报文,也就是 CONNACK 数据包。

        总结一句话就是:客户端先向服务端发送 CONNECT报文,服务端收到连接请求后,再向待连接的客户端发送 CONNACK 报文

CONNECT 报文
 

        如果此 CONNECT 报文的格式或内容不符合 MQTT 规范,则服务器会拒绝客户端的连接请求。

        CONNECT 报文包含的信息如下图所示:


        所谓报文就是一个数据包, MQTT 报文组成分为三个部分:固定头(Fixed header)、可变头(Variable header)以及有效载荷(Payload,消息体)。这里我们简单地介绍一下:

        固定头(Fixed header) : 存在于所有 MQTT 报文中, 固定头中有报文类型标识,可用于识别是哪种 MQTT 报文,譬如该报文是 CONNECT 报文还是 CONNACK 报文,亦或是其它类型报文。

        可变头(Variable header) : 存在于部分类型的 MQTT 报文中,报文的类型决定了可变头是否存在及其具体的内容。

         消息体(Payload) : 存在于部分类型的 MQTT 报文中, payload 就是消息载体的意思。


        clientId--客户端 id

        clientId 是 MQTT 客户端的标识,也就是 MQTT 客户端的名字,MQTT 服务端可通过 clientId 来区分不同的客户端。

        keepAlive--心跳时间间隔

        有些客户端并不经常发送消息给服务端, 对于这种客户端, MQTT 协议使用了类似心跳检测的方法来判断客户端是否在线。客户端在没有向服务端发送信息时(空闲时) ,可以定时向服务端发送一个心跳数据包,这个心跳包也被称作心跳请求, 心跳请求的作用正是用于告知服务端,当前客户端依然在线。
        譬如 keepAlive=60,表示告诉服务端,客户端将会每隔 60 秒左右向服务端发送心跳包。


        cleanSession--清除会话

        这是一个布尔值, cleanSession 标志可用于控制客户端与服务端在连接和断开连接时的行为,我们举个例子来进行说明, QQ、微信这些聊天软件大家都用过,假设当前你的 QQ 账号没有登录或者说当前处于离线状态,与服务器断开了连接; 而在离线期间,你的 QQ 好友给你发了几条信息; 由于当前你的 QQ 处于离线状态,自然是接收不到好友发送过来的信息,但是, 当你的 QQ 恢复连接状态时,立马会接收到好友在离线期间所发给你的信息

        如果连接服务端时 cleanSession=0, 当 MQTT 客户端由离线(与服务端断开连接)再次上线时,离线期间发给客户端的所有 QoS>0 的消息仍然可以接收到;如果连接服务端时 cleanSession=1, 当 MQTT 客户端由离线(与服务端断开连接)再次上线时,离线期间发
给客户端的所有消息一律接收不到。
        说白了,想接收离线消息, 客户端连接服务端时就必须使用 cleanSession=0;除了这个作用之外,如果cleanSession=0,则 MQTT 服务端会在客户端断开连接之后“记住” MQTT 客户端在线期间所订阅的所有“主题”;也就是说,服务端会保存、存储客户端所订阅的主题。
        如果 cleanSession=1,客户端既无法接收到离线消息、服务端也不会记住该客户端所订阅的主题, 服务端不会保存客户端的会话状态, 每次连接都是一次新的会话

下面再看看 MQTT 服务端接收到客户端发来的连接请求后所回复的 CONNACK 报文详细内容


CONNACK 报文


returnCode--连接返回码


        当服务端收到了客户端的连接请求后,会向客户端发送 returnCode(连接返回码), 用来说明连接情况。如果客户端与服务端成功连接,则返回数字“0”。如果未能成功连接,返回码将会是一个非零的数字,具体这个数字的含义,请见下表


       sessionPresent


        在 cleanSession=0 的情况下, 当客户端连接到服务器之后, 可通过 CONNACK 报文中返回的sessionPresent 来查询服务端是否为客户端保存了会话状态(客户端上一次连接时的会话状态信息) , 如果服务端已为客户端保存了上一次连接时的会话状态,则 sessionPresent=1,如果没有保存会话状态,则sessionPresent=0。

        如果 cleanSession=1, 在这种情况下,客户端是不需要服务端保存会话状态的, 那么服务端发送的确认连接 CONNACK 报文中, sessionPresent 肯定是 false(sessionPresent=0) ,也就是说,服务端没有保存客户端的会话状态信息。

        简言之, CONNACK 报文的 sessionPresent 与 CONNECT 报文的 cleanSession 相互配合。其作用是客户端发送连接请求时,服务端告知客户端有没有保存会话状态。这个被服务端保存的会话状态是来自于上一次客户端连接时,譬如离线消息以及上一次连接时客户端所订阅的主题。

断开连接
 

        当 MQTT 客户端连接到服务端之后,在后续的通信过程中,如果客户端想要断开与服务端的连接,此时客户端可以主动向服务端发送一个 DISCONNECT 报文来断开与服务端的连接,如下图所示

发布消息、订阅主题与取消订阅主题
 

PUBLISH– 发布消息
        当客户端连接到服务端之后,就可以向服务端发布消息了, 每条发布的消息必须指定一个“主题”,表示向某主题发布消息,MQTT 客户端向服务端发布消息其实就是向服务端发送一个 PUBLISH 报文, 服务端收到客户端发送过来的 PUBLISH 报文之后,会向发送发回复一个报

SUBSCRIBE--订阅主题
        客户端要想订阅主题,首先要向服务端发送主题订阅请求。客户端是通过向服务端发送 SUBSCRIBE 报文来实现这一请求的。该报文包含有一系列“订阅主题名”。请留意,一个 SUBSCRIBE 报文可以包含有单个或者多个订阅主题名。也就是说,一个 SUBSCRIBE 报文可以用于订阅一个或者多个主题。

        另外每一个 SUBSCRIBE 报文还包含有“报文标识符”。报文标识符可用于对 MQTT 报文进行标识。不同的 MQTT 报文所拥有的标识符不同。 MQTT 设备可以通过该标识符对 MQTT 报文进行甄别和管理。当客户端向服务端发送 SUBSCRIBE 报文,服务端接收到 SUBSCRIBE 报文之后会向客户端回复一个SUBACK 报文(订阅确认报文),如下图所示:

UNSUBSCRIBE--取消订阅主题
 

        客户端订阅了某一主题之后,可以随时取消订阅, MQTT 协议提供了这样的操作。

客户端通过向服务端发送一个 UNSUBSCRIBE 报文来取消订阅主题,当服务端接收到 UNSUBSCRIBE报文后,会向发送发回复一个 UNSUBACK 报文(取消订阅确认报文),如下图所示:

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

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

相关文章

极客时间:使用Autogen Builder和本地LLM(Microsoft Phi3模型)在Mac上创建本地AI代理

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

Jenkins教程-15-常用插件-Blue Ocean

上一小节我们学习了Jenkins定时任务构建的方法,本小节我们讲解一下Jenkins常用插件Blue Ocean的使用方法。 Blue Ocean 提供了一套可视化操作界面来帮助创建、编辑 Pipeline 任务。 Blue Ocean 特性: 流水线编辑器:用于创建贯穿始终的持续交…

JavaScript学习笔记(七)

45.9 JavaScript 可迭代对象 可迭代对象&#xff08;Iterables&#xff09;是可以使用 for..of 进行迭代的对象。 从技术上讲&#xff0c;可迭代对象必须实现 Symbol.iterator 方法。 45.9.1 遍历字符串 <body><p id"demo"></p><script>c…

关于centos7自带的nginx1.20.1开启https后,XP系统的IE6和IE8无法显示网页的问题

CentOS7自带的nginx-1.20.1是支持HTTP/2和TLS1.3的。 软件包名称&#xff1a;nginx-1.20.1-10.el7.x86_64 CentOS7默认开启了HTTP/2&#xff0c;但没有开启TLS1.3&#xff0c;以及IE6和IE8的https访问。 开启方法&#xff1a; ssl_ciphers HIGH:!aNULL:!MD5;改为ssl_ciphers…

1-3分钟爆款视频素材在哪找啊?这9个热门爆款素材网站分享给你

在如今快节奏的时代&#xff0c;短视频已成为吸引观众注意力的黄金手段。然而&#xff0c;要制作出1-3分钟的爆款视频&#xff0c;除了创意和剪辑技巧外&#xff0c;选择合适的素材至关重要。那么&#xff0c;哪里可以找到那些能让你的视频脱颖而出的爆款素材呢&#xff1f;不用…

【UE5.1】Chaos物理系统基础——05 蓝图绑定Chaos破裂或碰撞事件

步骤 1. 新建一个父类为Actor的蓝图&#xff0c;这里命名为“BP_ChaosExplosionEvent” 打开“BP_ChaosExplosionEvent”&#xff0c;添加一个变量&#xff0c;这里命名为“GC”&#xff0c;变量类型为“几何体集actor”&#xff0c;设置为可编辑实例 在事件图表中添加如下节点…

ELK+Filebeat+Kafka+Zookeeper

本实验基于ELFK已经搭好的情况下 ELK日志分析 架构解析 第一层、数据采集层 数据采集层位于最左边的业务服务器集群上&#xff0c;在每个业务服务器上面安装了filebeat做日志收集&#xff0c;然后把采集到的原始日志发送到Kafkazookeeper集群上。第二层、消息队列层 原始日志发…

通过端口转发实现docker容器运行时端口更改

通过端口转发实现docker容器运行时端口更改 前言启动容器查看容器ip地址端口转发 前言 关于修改docker正在运行中容器端口&#xff0c;网上大部分分为3类: 1. 删除原有容器重新创建;2. 改配置文件;3. 在现有容器上新提交镜像&#xff0c;用新镜像起新的容器。 1和3属于同一种流…

Matlab手搓线性回归-非正规方程法

原理&#xff1a;wxb&#xff0c;x是输入&#xff0c;求得的结果与真实值y求均方误差。 采用链式法则求导 参数更新&#xff0c;梯度下降法&#xff08;批量梯度下降&#xff09; 随机生成数据&#xff1a; m100&#xff1b;生成100个数据&#xff0c;并添加随机噪声 clear; …

9、Python之文本解析:字符串格式化的逆操作?

引言 前面的文章中&#xff0c;提到了关于Python中字符串中的相关操作&#xff0c;更多地涉及到了字符串的格式化&#xff0c;有些地方也称为字符串插值操作&#xff0c;本质上&#xff0c;就是把多个字符串拼接在一起&#xff0c;以固定的格式呈现。 关于字符串的操作&#…

2021版本的idea热部署的详细步骤

背景&#xff1a;我是自己用的是2021版本的idea,然后发现跟2023版本的热部署不太一样&#xff0c;所以&#xff0c;今天自己出一期这样的文章吧&#xff01;&#xff01;&#xff01;其他人配置的时候根据自己的情况&#xff0c;来阅读吧&#xff01; 第一步&#xff1a;方式一…

光伏项目开发合作模式

光伏项目开发合作模式多种多样&#xff0c;根据应用场景的不同&#xff0c;主要分为户用光伏项目合作模式和工商业光伏项目合作模式。本文将分别介绍这两种模式的特点和常见形式&#xff0c;帮助大家更好地了解光伏项目开发的市场运作。 一、户用光伏项目合作模式 1.用户全款购…

科研训练课程——2024/7/8

科研训练课程——2024/7/8 文章目录 前言课程任务&#xff08;可跳过&#xff09;了解1. LetPub2. Web of Science 总结 前言 本系列笔记为记录大二暑期学校课程—— 科研训练与写作&#xff0c;记录一下每天了解了什么吧&#xff08;苦逼又无聊的学习生涯又开始了。才刚结束啊…

matlab仿真 信道(上)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第四章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; 1.加性高斯白噪声信道&#xff08;AWGN &#xff09; clear all t0:0.001:10; xsin(2*pi*t);%原始信号 snr20;%设定加性白噪…

基于flask的猫狗图像预测案例

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️如遇文章付费&#xff0c;可先看…

遥感分类产品精度验证之TIF验证TIF

KKB_2020.tif KKB_2020_JRC.tif kkb.geojson 所用到的包&#xff1a;&#xff08;我嫌geopandas安装太麻烦colab做的。。 import rasterio import geopandas as gpd import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.metrics import c…

【Threejs进阶教程-着色器篇】3. Uniform的基本用法2与基本地球昼夜效果

Uniform的基本用法2 关于本Shader教程前两篇地址&#xff0c;请按顺序学习本篇使用到的资源用uniform传递纹理代码分析texture类型的uniform在shader中接收uniformtexture2D()处理图片压缩修改wrapS和wrapT 切换成夜景效果切换Mix() 昼夜切换升级改动代码效果分析解决球体分界线…

Linux dig命令常见用法

Linux dig命令常见用法 一、dig安装二、dig用法 DIG命令(Domain Information Groper命令)是常用的域名查询工具&#xff0c;通过此命令&#xff0c;你可以实现域名查询和域名问题的定位&#xff0c;对于网络管理员和在域名系统(DNS)领域工作的小伙伴来说&#xff0c;它是一个非…

【大模型LLM面试合集】大语言模型架构_attention

1.attention 1.Attention 1.1 讲讲对Attention的理解&#xff1f; Attention机制是一种在处理时序相关问题的时候常用的技术&#xff0c;主要用于处理序列数据。 核心思想是在处理序列数据时&#xff0c;网络应该更关注输入中的重要部分&#xff0c;而忽略不重要的部分&…

YOLOv8改进 | 注意力机制| 引入多尺度分支来增强特征表征的注意力机制 【CVPR2021】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…