Mosquitto --topic
订阅树的概念
Mosquitto通过订阅树的方式来管理所有的topic以及客户端的订阅关系,它首先将所有的topic按照/分割并组织成一棵树结构,从根节点到树中的每个节点即组成该节点所对应的一个topic,每个topic都保存一个订阅列表,该订阅列表中保存了所有订阅当前topic的客户端信息。例如有如下订阅关系:
客户端a1,a2,a3订阅了topic:A1/B1/C1m
客户端b1,b2订阅了topic:A2/B2/C2
客户端c1,c2订阅了topic:A1/B1/C3
客户端d1订阅了topic:A2/B3
则上述订阅树如图。

Mosquitto程序在实现中根据topic消息的性质将订阅树分为两颗子树:业务子树和系统子树;mosquitto程序中将topic分为两种类型来处理:系统topic和业务topic,前者主要用于发布和维护mosquitto内部的系统消息,后者的topic是用户订阅的业务topic,做这种区分的原因是因为这两种的类型的topic性质和实现方式上有许多差别,这种差别主要体现在以下3点:
1)生存周期不同,系统topic无论是否有用户订阅都会存在与订阅树中,而业务topic必须有客户端订阅才能存在(除非其消息字段retain设置为1)。
2)创建方式不同,系统topic在消息发布时进行创建,业务topic即可以在订阅时创建也可以在消息发布时创建(此时需要该消息retain字段设置为1)。
3)消息保存方式不同,凡是发布到系统topic的消息都会被保存下来,业务消息将直接挂到订阅列表的各context的消息队列中,如果没有连接订阅或未设置其retain字段,消息将不会被保存下来,消息的retain字段是否被设置在函数mqtt3_handle_publish进行检查。
订阅树的创建:(在src/database.c中的mqtt3_db_open函数实现)
mosquitto程序启动时将创建订阅树,该过程将创建三个节点:订阅树总根节点、业务子树根节点和系统子树根节点,这两个子树根节点作为订阅树总根节点的两个子节点,其中订阅树总根节点和业务子树的根节点中topic成员的值为空字符串,而系统子树根节点中保存的值为“$SYS”,如图:

搭建订阅树
1) 系统子树搭建过程
Mosquitto中,系统子树在发布系统消息时,自动检测topic片段是否存在,如果不存在则在系统topic上创建节点以搭建订阅树。搭建过程如下:
将Topic按照“/"分成 topic片段;根据第一个topic片段“$SYS”遍历订阅树的子节点找到系统子树的根节点;根据topic下一个片段查找系统子树,若没有则创建这个节点,依次方案处理直至topic片段解析完。
所用到的函数调用: mqtt3_db_messages_easy_queue(在src/database.c中) --->mqtt3_db_messages_queue (在src/subs.c中) ---> _sub_add(在src/subs.c中)
2)业务子树搭建过程
分为两种类型:订阅时创建和消息发布时创建。后者与系统Topic的方式类似。前者在收到订阅请求后将该客户端挂到对应的业务子树节点的订阅列表中,若不存在客户端所订阅的Topic,则会自动为之添加相应节点。
所用到的函数调用: mqtt3_handle_subscribe(在src/read_handle_server.c中) --->mqtt3_sub_add(在src/subs.c中) --->_sub_add(在src/subs.c中)
可以看到,在上面都使用了_sub_add函数,而调用它的分别是mqtt3_db_messages_queue 和mqtt3_sub_add函数,而且这三个函数都是在src/subs.c中,不妨来看看它们的逻辑。
mqtt3_db_messages_queue:(系统子树的搭建)



这几张图把订阅树的构建的大致逻辑勾勒出来。可以看见业务子树和系统子树的搭建大致逻辑相似,但是在局部处理上还是有区别,最大的区别就是如果创建业务子树的时候如果有没有找到topic片段,则会向订阅树中添加相应节点,而创建系统子树时则不会(原因见前面提到的二者的区别的第二点)。
还有就是这里在根据用户发布的topic(一个字符串)来在树结构中查询,用到了一个技巧,就是调用_sub_topic_tokenise函数将这个字符串分解,并组成一个链表的形式,然后通过遍历这个链表逐步完成对树结构的查询、添加等工作,最后释放掉这个链表。这里的链表就相当于一个缓冲区,值得借鉴。
例如一个Topic: year/month/day
就被转换为如下链表结构:

Mosquitto --topic的更多相关文章
- 五、Mosquitto 高级应用之权限管理
本文将讲解 Mosquitto 权限管理.如果还没有搭建 Mosquitto 服务的可以参考我的另外两篇文章<< 一.Mosquitto 介绍&安装>> << ...
- mosquitto --用户配置 及权限管理
mosquitto中可以添加多个用户,只有使用用户名和密码登陆服务器才允许用户进行订阅与发布操作.可以说用户机制是mosquitto重要的安全机制,增强服务器的安全性.用户与权限配置需要修改3处地方: ...
- mosquitto -- 权限配置
Mosquitto 权限是根据 topic 控制的.类似与目录管理.您可以设定每个用户订阅/发布权限.也可以设定每个用户可访问的topic范围.从而达到权限控制的目的. 这里我们需要我另外一个帖子(用 ...
- mosquitto $SYS下topic
$SYS/broker/clients/connected
- Mosquitto搭建Android推送服务(四)Mosquitto服务器用户登录与权限配置
文章钢要: 1.对服务器进行多用户配置 2.根据不同用户给予不同权限 一.Mosquitto的用户机制 mosquitto中可以添加多个用户,只有使用用户名和密码登陆服务器才允许用户进行订阅与发布操作 ...
- Mosquitto搭建Android推送服务番外篇一:各种报错解决
文章钢要: 目前笔者在开发搭建Mosquitto服务器,在此期间遇到很多实际问题,所以走了很多弯路,在这里写出来为大家提供一些帮助. 1.安装完成后启动Mosquitto报错 执行mosquitto客 ...
- Mosquitto搭建Android推送服务(三)Mosquitto集群搭建
文章钢要: 1.进行双服务器搭建 2.进行多服务器搭建 一.Mosquitto的分布式集群部署 如果需要做并发量很大的时候就需要考虑做集群处理,但是我在查找资料的时候发现并不多,所以整理了一下,搭建简 ...
- Mosquitto搭建Android推送服务(一)MQTT简介
总体概要: MQTT系列文章分为4部分 1.MQTT简介 2.mosquitto服务器搭建 3.编写Mosquitto的可视化工具 4.使用Mosquitto完成Android推送服务 文章钢要: 对 ...
- 借助mosquitto“实时”远程监控服务器数据库运行状态
公司的项目还处于开发阶段,我把整个后台服务临时放在阿里云上供前端测试,用的阿里云的ECS云服务器,HTTP请求服务器和数据库服务都安装在一台机子上(穷啊,凑合用),做测试用,配置相当低:单核1Gb.其 ...
随机推荐
- Codeforces 1131F Asya And Kittens (构造)【并查集】
<题目链接> 题目大意:有$n$只小猫,开始将它们放在指定的n个单元格内,然后随机从n-1个隔板中拆除隔板,最终使得这些小猫在同一单元格.现在依次给出拆除隔板的顺序,比如:1 4 就表示1 ...
- Tomcat v9.0 Could not publish to the server. java.lang.IndexOutOfBoundsException
今天使用Tomcat启动一个java项目,出现报错: Could not publish to the server. java.lang.IndexOutOfBoundsException 众寻之下 ...
- 3-6 Vue中的条件渲染
本次案例讲解:v-if,v-show,v-else,v-else-if和key值的相关用法!!! v-if指令: //通过一个(v-if)指令 ,可以结合js表达式的返回值,决定一个标签是否在页面上展 ...
- JVM 调优-给你的java应用看看病
目录 java 应用 1 cpu 负载过高 1.1 分析问题 1.2 解决方案 2 内存占用过多 2.1 从内存回收方面 2.2 从代码层面 java 应用 1 cpu 负载过高 1.1 分析问题 首 ...
- JavaScript 作用域的误区
了解JavaScript的同学可能知道,JavaScript语言由于设计原因,导致语言本身存在很多先天性的不足,当然这并非设计者有意的,js语言最初是被设计来作为网页交互的脚本语言,依照现有的js语法 ...
- 读取XML文件内容
myeclipse中类的格式 上面中的RunMain.java为程序执行的入口,JdbcUtil.java为实体类,XmlDocumentUtil.java执行解释xml文件与获取里面的属性,程序所需 ...
- Linux上的文件查找工具之locate与find
前言 Linux上提供了两款工具用于查找文件,一款是locate,另一款是find. locate的特点是根据已生成的数据库查找,速度较快,但是查找的是快照数据,不准确. 因此在日常使用中,为了准确性 ...
- 项目部署相关命令(pm2)
普通方式启动后台服务: nohup npm start & 关闭服务,需要找到进程号: lsof -i :3000 kill -9 进程号 通过pm2启动项目,可实现关闭自启动: 安装pm2: ...
- codeforces148----E. Porcelain
#include <iostream> #include <cstring> using namespace std; ; int s[maxn];//s[i]表示每行前i个数 ...
- 《C#图解教程》一览
本书针对编程新手和中级水平的程序员.笔者尽力专注 C# 语言本身,详尽深入地描述语言及各部分.少涉及 .NET 和相关编程实践.本书写作过程中,笔者始终坚持确保内容简洁性的同时又能透彻地讲解这门语言. ...