【MQTT基础篇(三)】连接MQTT服务端

2023-05-16

文章目录

  • 连接MQTT服务端
    • 1 CONNECT – 连接服务端
      • 1.1 clientId – 客户端ID
      • 1.2 cleanSession – 清除会话
      • 1.3 keepAlive – 心跳时间间隔
    • 2 CONNACK – 确认连接请求
      • 2.1 returnCode – 连接返回码
      • 2.2 sessionPresent – 当前会话

连接MQTT服务端

MQTT客户端之间要想实现通讯,必须要通过MQTT服务端。因此MQTT客户端无论是发布消息还是订阅消息,首先都要连接MQTT服务端。下面我们看一下MQTT客户端连接服务端的详细过程。

MQTT客户端连接服务端一共有两步。

  1. 首先MQTT客户端将会向服务端发送连接请求。该请求实际上是一个包含有连接请求信息的数据包。这个数据包的官方名称为CONNECT
    在这里插入图片描述
  2. MQTT服务端收到客户端连接请求后,会向客户端发送连接确认。同样的,该确认也是一个数据包。这个数据包官方名称为CONNACK
    在这里插入图片描述

1 CONNECT – 连接服务端

在上面的描述中我们看到。MQTT客户端要想连接服务端,首先要向服务端发送CONNECT报文。如果此CONNECT报文的格式或内容不符合MQTT规范,则服务器会拒绝客户端的连接请求。

下图是CONNECT报文所包含的信息内容。
在这里插入图片描述
在接下来的课程讲解中我们将会频繁接触到两个概念。第一个概念是报文,第二个概念是信息

所谓报文就是一个MQTT数据包。这个数据包中可能包含有多个信息。比如以上图片就是描绘了一个CONNECT报文(数据包)的详细内容。

在这个CONNECT报文(数据包)中包含有多个信息。上图左侧栏中的内容是CONNECT报文所包含的信息名称。右侧是信息的具体内容。如上图示例中,此CONNECT报文包含有名称为clientId的信息,该信息的内容是”client-1″。当然,上图只是一个示例,不是所有的CONNECT报文中的clientId信息内容都是”client-1″。

另外也请注意,上图中有些信息名称旁边标注了“可选”字样,而有些则没有。那些没有标注“可选”字样的信息是必须包含在CONNECT报文中的。而对于标注了“可选”字样的信息,CONNECT报文既可以包含它们也可以没有它们。

1.1 clientId – 客户端ID

ClientId是MQTT客户端的标识。MQTT服务端用该标识来识别客户端。因此ClientId必须是独立的。如果两个MQTT客户端使用相同ClientId标识,服务端会把它们当成同一个客户端来处理。通常ClientId是由一串字符所构成的,如上图所示,此示例中的clientID是“client-1”。


1.2 cleanSession – 清除会话

所谓“清除会话”这一翻译源自MQTT官方文档中文版。要说明cleanSession的具体含义,首先要从MQTT网络环境讲起。

MQTT客户端与服务端的连接可能不是非常稳定,在不稳定的网络环境下,要想保证所有信息传输都能够做到准确无误,这是非常困难的。因此,我们就要根据客户端对系统运行的重要性来区别对待。

有些MQTT客户端对整个系统运行起着关键作用,这些客户端一定要准确无误的收到服务端发来的报文。比如一辆自动驾驶汽车的导航系统。假如这个导航系统错过了服务端发来的报文,可能会导致交通事故甚至人员伤亡。因此,即使网络不是非常稳定,我们仍然要求汽车导航系统一定要准确无误的收到服务端所发来的报文。

但是有些MQTT客户端对整个系统运行并不是很重要。比如同样是这辆自动驾驶汽车。它的音乐播放系统如果没有及时收到服务端发来的音乐播放报文,这对驾驶系统来说影响不大。

以上所举的两个例子说明,MQTT通讯中有些客户端必须准确无误的收到报文,有些则不需要。

为了保证重要的MQTT报文可以被客户端准确无误的收到。在服务端向客户端发送报文后,客户端会向服务端返回一个确认报文。如果服务端没有收到客户端返回的确认报文,那么服务端就会认为刚刚发送给客户端的报文没有被准确无误的送达。在这种情况下,服务端将会执行以下两个操作:

  • 操作1:将尚未被客户端确认的报文保存起来**

  • 操作2:再次尝试向客户端发送报文,并且再次等待客户端发来确认信息。**

讲到这里就要看看cleanSession的作用了。

如果cleanSession 被设置为“true”。那么服务端不需要客户端确认收到报文,也不会保存任何报文。在这种情况下,即使客户端错过了服务端发来的报文,也没办法让服务端再次发送报文。其实我们从字面上也很容易理解。cleanSession 的第一个词是clean。这个词的意思是clean(干净)的。服务端一旦发送完报文,就会把报文忘得“干干净净”了。

反过来,如果我们将cleanSession 设置为”false”。那么服务端就知道,后续通讯中,客户端可能会要求我保存没有收到的报文。

从以上的描述不难看出,如果某个客户端用于收发非常重要的信息(比如前文示例中汽车自动驾驶系统),那么该客户端在连接服务端时,应该将cleanSession设置为”false”。这样才能让服务端保存那些没有得到客户端接收确认的信息。以便服务端再次尝试将这些重要信息再次发送给客户端。

相反的,如果某个客户端用于收发不重要的信息(比如前文示例中车载音乐系统)那么该客户端在连接服务端时,应该将cleanSession设置为”true”。

请注意,如果需要服务端保存重要报文,光设置cleanSession 为false是不够的,还需要传递的MQTT信息QoS级别大于0。

关于QoS的概念,我们会在本教程后续课程中详细讲解。到目前请您务必牢记,如果想让服务器记住重要报文,那么客户端在连接服务端时,需要把cleanSession中设置为false。这一点非常关键,请务必牢记。

1.3 keepAlive – 心跳时间间隔

KeepAlive (心跳时间间隔)正是用于服务端了解客户端连接情况的。不过关于KeepAlive (心跳时间间隔)目前讲解还为时过早,我们会在后续的课程中给您做详细介绍。目前您只需要记住,KeepAlive用于服务端实时了解客户端是否与其保持连接的情况。

以上就是CONNECT报文的主要内容。
下面为MQTT服务端接收到客户端发来的连接请求后所回复的CONNACK报文详细内容。


2 CONNACK – 确认连接请求

下图是CONNACK报文所包含的信息内容。
在这里插入图片描述

CONNACK报文包括两个信息。一个是returnCode(连接返回码),另一个是sessionPresent (当前会话)。以下是这两个信息的说明:


2.1 returnCode – 连接返回码

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

在这里插入图片描述


2.2 sessionPresent – 当前会话

要说明sessionPresent,首先我们要回顾一下CONNECT报文中的cleanSession – 清除会话。

我们还用自动驾驶汽车为例。对于自动驾驶汽车来说,自动导航系统属于非常重要的MQTT客户端。服务端发送给导航系统的报文必须要准确无误的送达。相反,音乐播放系统就不那么重要了。即使音乐播放系统错过服务端发送的报文也没有关系。

对于不重要的MQTT客户端,它们在向服务器发送连接请求时,CONNECT报文中的cleanSession通常设置为true。原因是这类不重要的MQTT客户端即使丢失信息也不会影响整体系统运行。因此服务端在看到客户端的cleanSession为true时,就不会保存发送给它们的信息。

然而对于汽车导航系统这类重要的MQTT客户端来说。当它在连接服务端时,cleanSession肯定时设置为false。原因是重要客户端需要服务端确保信息发送准确无误。如果服务端发现发送给重要客户端的信息没有得到确认,会将报文进行保存。

当重要客户端连接服务端时,服务端可能保存着没有得到确认的报文。如果是这样的话,那么客户端在连接服务端时,就会通过sessionPresent来了解服务端是否有之前未能确认的信息。

下面我们分几种情况来讲述sessionPresent的作用。

首先,当客户端发送的CONNECT报文中的cleanSession设置为true。在这种情况下,客户端是不需要服务端保存任何报文的。那么服务端发送的确认连接CONNACK报文中,sessionPresent肯定是false,也就是说,服务端没有保存任何报文。

当客户端发送的CONNECT报文中的cleanSession设置为false时,客户端是要求服务端保存报文的。在这种情况下,如果服务端的确保存了没有收到客户端接收确认的报文信息,那么cleanSessiontrue,否则为false

简言之,CONNACK报文的sessionPresentCONNECT报文的cleanSession相互配合。其作用是客户端发送连接请求时,服务端告知客户端有没有保存报文信息。这个被服务端保存的报文信息是来自于上一次客户端连接时,服务端曾经发送此报文给客户端,但是发送后没有收到客户端接收确认。


内容来自 -----> 太极创客
详情可见太极创客官网,内有Arduino、ESP32等详细教程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【MQTT基础篇(三)】连接MQTT服务端 的相关文章

  • APM固件太大放不下,咋办?

    APM固件越来越大 xff0c 小容量单片机放不下咋办 xff1f 原文链接 xff1a APM固件太大放不下 xff0c 咋办 xff1f 怒飞垂云 无人机知识库
  • 怒飞垂云视频教程 二、基于waf编译飞控固件

    原文链接 xff1a http www nufeichuiyun com p 61 246 怒而飞 xff0c 其翼若垂天之云 xff01 我是怒飞 QQ xff1a 3500985284
  • 怒飞垂云视频教程 三、基于eclipse编译飞控固件

    基于eclipse编译飞控固件 xff0c 原文链接 xff1a http www nufeichuiyun com p 61 249
  • 怒飞垂云视频教程 四、建立软件仿真环境

    原文链接 xff1a http www nufeichuiyun com p 61 256 怒而飞 xff0c 其翼若垂天之云 xff01 我是怒飞 QQ xff1a 3500985284
  • docker:国内 hub 镜像地址

    七牛云
  • C++读取STL模型文件

    数据格式 二进制的数据格式 xff1a 二进制STL文件用固定的字节数来给出三角面片的几何信息 80 80个字节的文件头 xff0c 用于存贮文件名 4 4 个字节的int描述模型的三角面片个数 小端存储 50 n 一个三角面片占用固定的5
  • mNetAssist(arm64)linux下图形界面的网络调试助手

    linux下图形界面的网络调试助手mNetAssist 网上均为x86 amd处理器的 想在arm64上使用 所以 自己down了源码编译了一遍 方便大家使用 项目地址 码云 https gitee com justsure m net a
  • 激光SLAM建图过程中的问题MessageFilter [target=odom_combined ]:Dropped 100.00% of messages so far.,解决方案

    最近在和师弟用kobuki底盘进行SLAM建图的过程中遇到一个比较棘手的问题 xff0c 一直没有解决 xff0c 直到今天我在仿真环境中也碰到了 WARN 1618301922 711685031 2351 764000000 Messa
  • Linux 内核优化-调大TCP最大连接数

    一 tcp 概述 1 服务器如何标识tcp连接 xff1f 在tcp应用中 xff0c server事先在某个固定端口监听 xff0c client主动发起连接 xff0c 经过三路握手后建立tcp连接 在确定最大连接数之前 xff0c 先
  • 飞书妙记用法小结

    企业升级后 xff0c 可以到达10G 妙记的2G不是指代识别容量 xff0c 而是指代源文件容量 额度满了以后 选择权益数据 那么如果容量满了的话 xff0c 怎么释放呢 xff1f 需要删除回收站里面的所有文件 xff0c 才可以释放
  • 3-1利用文件流复制文件内容-Java

    题目 xff1a 编程利用文件流把一个文本文件中的内容复制到另外一个文件中 解答 xff1a Test类 xff1a package Experiment 3 Question 1 import java io public class T
  • C++强制类型转换运算符(static_cast、reinterpret_cast、const_cast和dynamic_cast)

    将类型名作为强制类型转换运算符的做法是C语言的老式做法 xff0c C 43 43 为保持兼容而予以保留 C 43 43 引入了四种功能不同的强制类型转换运算符以进行强制类型转换 xff1a static cast reinterpret
  • 字符数组的初始化与赋值

    代码编译运行环境 xff1a VS2017 43 Win32 43 Debug 1 字符数组的初始化方式 C语言中表示字符串有两种方式 xff0c 数组和指针 xff0c 字符数组是我们经常使用的方式 变量的定义包括指明变量所属类型 变量名
  • XML和HTML之间的差异

    XML 不是 HTML 的替代 XML 和 HTML 为不同的目的而设计 xff1a XML 被设计用来传输和存储数据 xff0c 其焦点是数据的内容 HTML 被设计用来显示数据 xff0c 其焦点是数据的外观 HTML 旨在显示信息 x
  • 线程、线程句柄、线程ID

    什么是句柄 xff1a 句柄是一种指向指针的指针 我们知道 xff0c 所谓指针是一种内存地址 应用程序启动后 xff0c 组成这个程序的各对象是住留在内存的 如果简单地理解 xff0c 似乎我们只要获知这个内存的首地址 xff0c 那么就
  • Modbus通信协议

    一 Modbus 协议简介 Modbus 协议是应用于电子控制器上的一种通用语言 通过此协议 xff0c 控制器相互之间 控制器经由网络 xff08 例如以太网 xff09 和其它设备之间可以通信 它已经成为一通用工业标准 有了它 xff0
  • 77组合

    给定两个整数 n 和 k xff0c 返回 1 n 中所有可能的 k 个数的组合 示例 输入 n 61 4 k 61 2 输出 2 4 3 4 2 3 1 2 1 3 1 4 最容易想到的应该是回溯 xff0c 更多题目思路及代码见 xff
  • 结构体内数据元素对齐

    默认情况下 xff0c 为方便结构体内元素的访问于管理 xff0c 当结构体内的数据元素的长度小于处理器的位数的时候 xff0c 便以结构体内的最长数据元素为对齐单位 xff0c 即结构体的长度一定为最长数据元素的长度的整数倍 如果结构体内
  • 关于stm32中串口重定向问题详解(找个时间好好理解下)

    usart这部分代码我也是从网上copy出来的 xff0c 一下是作者的解释 xff1a 简单地说 xff1a 想在mdk 中用printf xff0c 需要同时重定义fputc函数和避免使用semihosting 半主机模式 xff09
  • 缓冲区溢出(buffer overflow)避免方法

    什么是缓冲区溢出 xff1f copy数据进buffer时 xff0c 数据长度超过buffer中的剩余空间 缓冲区溢出的危害 xff1f 缓冲区溢出 xff0c 结果随机 xff0c 可能会导致程序功能不正常 xff0c 也可能导致程序崩

随机推荐

  • 【嵌入式系统应用开发】ROS环境安装配置与入门实操

    目录 前言1 ROS简介2 ROS软件安装2 1 添加ROS软件源2 2 添加密钥2 3 安装ROS2 4 初始化rosdep2 5 设置环境变量2 6 安装rosinstall 3 ROS初试 小海龟3 1 启动ROS Master3 2
  • 头文件包含的合理顺序

    如果包含顺序不当 xff0c 可能出现包含顺序依赖问题 xff0c 甚至引起编译错误 推荐如下顺序 xff1a 在头文件中 xff1a xff08 1 xff09 包含当前工程中所需要的自定义头文件 xff08 顺序自定 xff09 xff
  • windows下使用 SITL 模拟飞行——APM

    1 环境配置 按照官网教程配置环境 xff0c 链接 xff1a https ardupilot org dev docs building setup windows cygwin html building setup windows
  • Nvidia Xavier Nx平台修改CAN时钟调试记录

    1 前言 JETSON NX开发板上配置CAN bus与一个CAN收发器SN65HVD230 要求是改变设备树中的CAN时钟速率 让CAN时钟修改为40MHZ 2 如何设置准确的40MHz 要实现40MHz 首先需要设置CAN父时钟为pll
  • 【CMake】常见目录——10.1安装项目

    CMake中的目录 常见目录所代表的含义 PROJECT SOURCE DIR xff1a 工程的根目录 PROJECT BINARY DIR xff1a 运行cmake命令的目录 xff0c 通常为 PROJECT SOURCE DIR
  • 编译的时候所使用的动态库中出现错误:未定义的引用

    1 使用makefile编译的时候 xff0c 出现错误如下 xff1a 如上图所示 xff0c 是在动态库libicdbapi so中出现了未定义错误 xff0c 既然是未定义错误 xff0c 说明sqlprct sqlnult这5个符号
  • STL1:简介

    STL1 简介 1 背景1 1 STL是什么 xff1f 1 2 STL与C 43 43 标准库的关系1 3 版本 2 STL的组成3 容器分类4 迭代器分类4 1 分类原则 xff1a 访问方式4 2 分类原则 xff1a 操作类型4 3
  • Linux网络编程 5 - select模式的TCP服务器

    为了同时处理多个客户端的连接 xff0c 上一篇介绍了利用多线程的方法实现 xff0c 每个连接新建一个线程 xff0c 然后各自去处理 这是最简单也是最容易想到的方式 客户端的连接存在 xff0c 线程就存在 但是 xff0c 对于每一个
  • c标准库—参考手册

    1 lt errno h gt 2 lt float h gt 3 lt limits h gt 4 lt locale h gt 5 lt math h gt 6 lt signal h gt 7 lt setjmp h gt 8 lt
  • MPU6050

    1 个人总结 常用的MPU6050有八个针脚 xff0c VCC 跟GND 给模块供电 xff0c 模块通讯方式采用IIC通讯 xff0c SCL跟SDA为信号传递通道 xff0c XDA 跟 XCl是用来外接电磁传感器 xff0c 玩过M
  • 自学 Python 第一天

    总结 xff1a 感觉Python 前边学起来 跟c差不多 xff0c 之前学习过c语言 xff0c 但是并没有学这么细 xff0c 刚好学python xff0c 把当时忽略的知识点 重新减一下 打算花费两周学完Python为后续学习Op
  • 多功能悬赏任务平台app+小程序源码开源版搭建开发

    悬赏任务app源码 xff0c 从名字本身就可以理解这个PHP项目的流程 通过在线管理员工任务 即使它也可以在Intranet中工作 MySQL数据库是此源代码的最终部分 它易于实施和遵循 它是所有企业公司的主要项目应用程序 IT公司的任务
  • usart串口发送与接收问题

    项目场景 xff1a 串口通信可以说很常用的一种通信方式 xff0c 例如 蓝牙通信 openmv 与串口 通信 等等 问题描述 1 我们在进行数据传输过程中数据不时出现丢失的情况 xff0c 偶尔会丢失一部分数据 xff0c 导致数据部分
  • 基于51单片机光照强度检测系统

    介绍 本设计采用单片机作为数据处理与控制单元 xff0c 为了进行数据处理 xff0c 通过光敏电阻来感应光强弱变化 xff0c 经过ADC0804转换 xff0c 直接将数字信号送入到单片机中进行数据处理 单片机数据处理之后 xff0c
  • 基于51单片机控制的波形输出

    介绍 本模块采用PCF8591 xff0c 它是一款AD DA集成芯片 所以本节对iic通信协议不做过多的介绍 xff0c 重心放在iic的rtl建模 xff0c 本次通过iic控制PCF8591实现DAC输出功能 及输出波形 将数字量转为
  • 基于51单片机通过译码器控制系统

    用二极管 开关 译码器 单片机 数码管 xff08 点阵显示器 xff09 等器件设计仿真电路 xff0c 实现的功能 xff0c 用红黄绿二极管分别连接开关作为3 8译码器的输入 xff0c 译码器的输出连接到单片机的端口 xff0c 单
  • 基于51单片机串口通信的实验

    串口介绍 串口是一种应用十分广泛的通讯接口 xff0c 串口成本低 容易使用 通信线路简单 xff0c 可实现两个设备的互相通信 单片机的串口可以使单片机与单片机 单片机与电脑 单片机与各式各样的模块互相通信 xff0c 极大的扩展了单片机
  • 【QT】设置子窗口显示位置

    QT通过setGeoment来设置子窗口的位置 QWidget span class token operator span widget test span class token operator 61 span new span cl
  • 【散文诗】C语言的本质(基于ARM深入分析C程序)

    文章目录 1 ARM架构ARM通用寄存器及其别名基本汇编指令LDR xff1a STR xff1a ADD xff1a SUB xff1a BL xff1a PUSH xff1a POP xff1a MOV xff1a 2 局部变量的分配与
  • 【MQTT基础篇(三)】连接MQTT服务端

    文章目录 连接MQTT服务端1 CONNECT 连接服务端1 1 clientId 客户端ID1 2 cleanSession 清除会话1 3 keepAlive 心跳时间间隔 2 CONNACK 确认连接请求2 1 returnCode