MQTT 订阅标识符详解

news2024/10/7 16:23:44

为什么需要订阅标识符

在大部分 MQTT 客户端的实现中,都会通过回调机制来实现对新到达消息的处理。

但是在回调函数中,我们只能知道消息的主题名是什么。如果是非通配符订阅,订阅时使用的主题过滤器将和消息中的主题名完全一致,所以我们可以直接建立订阅主题与回调函数的映射关系。然后在消息到达时,根据消息中的主题名查找并执行对应的回调函数。

但如果是通配符订阅,消息中的主题名和订阅时的主题过滤器将是两个不同的字符串,我们只有将消息中的主题名与原始的订阅挨个进行主题匹配,才能确定应该执行哪个回调函数。这显然极大地影响了客户端的处理效率。

MQTT Subscription

另外,因为 MQTT 允许一个客户端建立多个订阅,那么当客户端使用通配符订阅时,一条消息可能同时与一个客户端的多个订阅匹配。

对于这种情况,MQTT 允许服务端为这些重叠的订阅分别发送一次消息,也允许服务端为这些重叠的订阅只发送一条消息,前者意味着客户端将收到多条重复的消息。

而不管是前者还是后者,客户端都不能确定消息来自于哪个或者哪些订阅。因为即使客户端发现某条消息同时与自己的两个订阅相匹配,也不能保证在服务端向自己转发这条消息时,这两个订阅是否都已经成功创建了。所以,客户端无法为消息触发正确的回调。

MQTT Subscription

订阅标识符的工作原理

为了解决这个问题,MQTT 5.0 引入了订阅标识符。它的用法非常简单,客户端可以在订阅时指定一个订阅标识符,服务端则需要存储该订阅与订阅标识符的映射关系。当有匹配该订阅的 PUBLISH 报文要转发给此客户端时,服务端会将与该订阅关联的订阅标识符随 PUBLISH 报文一并返回给客户端。

Subscription Identifier

如果服务端选择为重叠的订阅分别发送一次消息,那么每个 PUBLISH 报文都应该包含与订阅相匹配的订阅标识符,而如果服务端选择为重叠的订阅只发送一条消息,那么 PUBLISH 报文将包含多个订阅标识符。

客户端只需要建立订阅标识符与回调函数的映射,就可以通过消息中的订阅标识符得知这个消息来自哪个订阅,以及应该执行哪个回调函数。

MQTT Subscription

在客户端中,订阅标识符并不属于会话状态的一部分,将订阅标识符和什么内容进行关联,完全由客户端决定。所以除了回调函数,我们也可以建立订阅标识符与订阅主题的映射,或者建立与 Client ID 的映射。后者在转发服务端消息给客户端的网关中非常有用。当消息从服务端到达网关,网关只要根据订阅标识符就能够知道应该将消息转发给哪个客户端,而不需要重新做一次主题的匹配和路由。

一个订阅报文只能包含一个订阅标识符,如果一个订阅报文中有多个订阅请求,那么这个订阅标识符将同时和这些订阅相关联。所以请尽量确保将多个订阅关联至同一个回调是您有意为之的。

如何使用订阅标识符

  1. 在 Web 浏览器上访问 MQTTX Web。

  2. 创建一个使用 WebSocket 的 MQTT 连接,并且连接免费的公共 MQTT 服务器:

    MQTT over WebSocket

  3. 连接成功后,我们先订阅主题 mqttx_4299c767/home/+,并指定 Subscription Identifier 为 1,然后订阅主题 mqttx_4299c767/home/PM2_5,并指定 Subscription Identifier 为 2。由于公共服务器可能同时被很多人使用,为了避免主题与别人重复,这里我们将 Client ID 作为主题前缀:

    New Subscription 1

    New Subscription 2

  4. 订阅成功后,我们向主题 mqttx_4299c767/home/PM2_5 发布一条消息。我们将看到当前客户端收到了两条消息,消息中的 Subscription Identifier 分别为 1 和 2。这是因为 EMQX 的实现是为重叠的订阅分别发送一条消息:

    Receive MQTT Messages

  5. 而如果我们向主题 mqttx_4299c767/home/temperature 发布一条消息,我们将看到收到消息中的 Subscription Identifier 为 1:

    image.png

到这里,我们通过 MQTTX 演示了如何为订阅设置 Subscription Identifier。如果你仍然好奇如何根据 Subscription Identifier 来触发不同的回调,可以在 这里 获取 Subscription Identifier 的 Python 示例代码。

版权声明: 本文为 EMQ 原创,转载请注明出处。
原文链接:https://www.emqx.com/zh/blog/subscription-identifier-and-subscription-options

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

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

相关文章

chatglm微调

chatGML 看到 【【官方教程】ChatGLM-6B 微调:P-Tuning,LoRA,Full parameter】 【精准空降到 15:27】 https://www.bilibili.com/video/BV1fd4y1Z7Y5/?share_sourcecopy_web&vd_sourceaa8c13cff97f0454ee41e1f609a655f1&t927 记得看…

Java Mybatis02+oracle拓展

0目录 Mybatis 02Oracle 拓展 1.Mybatis 02 创建数据库和表 创建工程 实体类 util工具类 接口方法 Resource Mapper xml文件 配置文件 测试 加入模糊查询(根据姓名) 测试结果 2.ParameterType语法 实战 参数为对象 参数为…

Bean 作用域与生命周期

Bean 作用域与生命周期 ​ 对于 Spring 来说,核心操作对象就是存和取 Bean ,接下来就 Bean 的作用域与生命周期进行探讨。 文章目录 Bean 作用域与生命周期一、作用域的定义1.1、Bean 的6种作用域1.2、Bean作用域设置方法 二、Bean 的生命周期2.1、Bean…

【Java】Java实现微信小程序发送服务通知

文章目录 前言一、文档来源二、JAR包引入三、后端工作四、编写配置文件配置一:WxConfig配置二:WxProperties 五、代码编写 前言 在上个月接到一个需求,大概是需要计算一条数据的最大办理时间从而发送任务超期的微信小程序服务通知&#xff0…

怎么进行流程图制作?分享几种绘制方法

怎么进行流程图制作?流程图是一种图形化表示流程的图表,通常用于描述业务、计划或工作流程。它可以帮助人们更好地理解复杂的流程,并且提供了一种清晰的方法来记录和共享流程信息。下面介绍一些绘制流程图的方法,可以帮助我们快速…

4 自动微分 Automatic Differentitaion

计算图 Computational Graph 图上的每个节点代表一个中间值边事输入输出的关系 forward 求导 forward mode AD 上图中从前向后,一步一步计算每个中间值对 x1的偏导,那么计算到 v7,就得到了整个函数对于 x1的偏导。 有limitation 对一个参数…

echarts开发遇到的问题

echarts开发遇到的问题 1.rich富文本标签作为横向柱状图的刻度标签,其中带有icon。rich里不能写参数,只能写死?圆角设置无效? 解决办法: 自己写横向柱状图 散点图性能优化配置的临界点,最低优化数值必须…

超全整理,软件测试高频面试题(功能/接口/自动化测试-附答案)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 功能测试 1、双十…

LCD—STM32液晶显示(4.液晶控制代码讲解)

目录 STM32液晶控制代码讲解 液晶接口封装介绍 使用LCD的配置步骤 内存操作要使用volatile进行修饰 图形绘制实现 绘制矩形 重点补充 STM32液晶控制代码讲解 液晶接口封装介绍 指南者液晶接口原理图 左边DB00—DB15表示液晶屏的数据线引脚,分别对应STM32的F…

使用ppocr突然退出问题

本次使用conda装了一个cuda10.2版本的paddleocr,然后所有的环境检查没问题,使用paddle自带的检查代码,输出提醒paddle可以正常使用: >>> import paddle >>> paddle.utils.run_check() 输出结果提示安装正常 …

零编程经验也能打造精美微信展示小程序的秘诀揭秘

随着微信的普及和发展,微信展示小程序成为了许多企业展示自己形象的重要渠道。那么如何快速地搭建一个精美的微信展示小程序呢?下面就为大家详细介绍一下具体操作步骤。 首先,进入【乔拓云】平台后台。乔拓云是一款非常优秀的小程序开发平台&…

php伪协议(文件包含)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 php伪协议 伪协议详情 php伪协议 文件包含直接读取的是文件,而不是文件源码,所以要想办法读取源码方法。 那么就要涉及到 PHP 伪协议 ph…

LabVIEW开发航空电子设备嵌入式诊断半物理仿真系统

LabVIEW开发航空电子设备嵌入式诊断半物理仿真系统 航电集成系统是现代战争飞机的重要组成部分,包括惯性导航系统、飞行控制系统、机电管理系统和任务计算机等子系统。战机的作战性能与航电系统息息相关,可以说,没有高性能的空电系统&#x…

行业首家!法大大荣获“数据安全管理能力认证(DSMC)”证书

7月11日,法大大获得由中国信息通信研究院(以下简称“中国信通院”)颁发的“数据安全管理能力认证(DSMC)证书”(以下简称“DSMC证书”),成为行业内首家获颁该证书的企业,法…

基于Java+SpringBoot+Vue前后端分离校园管理系统详细设计和实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

Spring Cloud Alibaba【创建支付服务生产者、创建服务消费者 、Dubbo和OpenFeign区别 、微服务接入OpenFeign】(二)

目录 分布式服务治理_创建支付服务生产者 分布式服务治理_创建服务消费者 服务调用_Dubbo和OpenFeign区别 服务调用_微服务接入OpenFeign 分布式服务治理_创建支付服务生产者 创建服务提供者工程cloud-provider-payment8001 POM文件引入依赖 <dependencies><…

MP4怎么转换为gif的格式?快试试这两个方法!

想要将MP4视频文件转换为GIF格式&#xff1f;不用担心&#xff0c;本文将为您介绍两种简单易行的方法&#xff1a;记灵在线工具和使用FFmpeg命令行工具。这些方法适用于不同的用户&#xff0c;无论您是喜欢在线工具还是偏向命令行操作&#xff0c;都能找到适合自己的方式。让我…

开源代码分享(8)—大规模电动汽车时空耦合双层优化调度(附matlab代码)

参考文献&#xff1a; [1]He L , Yang J , Yan J , et al. A bi-layer optimization based temporal and spatial scheduling for large-scale electric vehicles[J]. Applied Energy, 2016, 168(apr.15):179-192. DOI:10.1016/j.apenergy.2016.01.089 1.基本原理 1.1摘要 电…

Python模块基础

一、模块 模块可以看成是一堆函数的集合体。 一个py文件内部就可以放一堆函数&#xff0c;因此一个py文件就可以看成一个模块。 如果这个py文件的文件名为module.py&#xff0c;模块名则是module。 1、模块的四种形式 在Python中&#xff0c;总共有以下四种形式的模块&…

MySQL约束和查询

约束和查询 1. 约束1.1 约束类型1.2 常用的约束 2. 查询2.1 聚合查询2.1.1 聚合函数2.1.2 GROUP BY2.1.3 HAVING 2.2 联合查询2.2.1 内连接2.2.2 外连接 2.3 合并查询 1. 约束 1.1 约束类型 NOT NULL - 指示某列不能存储 NULL 值。UNIQUE - 保证某列的每行必须有唯一的值。DE…