引言: 在mosquitto源码的src/subs.c 文件中存在一个mqtt3_sub_tree_print,它的作用是打印整个订阅树。这实际上也是遍历整个订阅树查找的过程,对于理解订阅树、当前sever端存储的内容都有十分重要的帮助。 如何调用mqtt3_sub_tree_print 笔者发现调用它需要开启另一个bool型变量flag_tree_print,该值默认情况下为false,故不打印树结构。这个变量是在src/mosquitto.c中定义,而在src/mosquitto.c文件中的handle_sigusr2()函数使这个变量为true。即当server端收到SIGUSR2信号时就会打印该信息。那什么是SIGUSR2?度娘告诉我们,它是一个自定义信号,这个信号由这条命令“kill -USR2 14932(PID号)”产生。当然,具体到这里,也就是当你在一个窗口内键入“mosquitto”时,开启新的窗口,输入刚才的命令,则在第一个窗口中可以显示打印出来的订阅树信息。 mqtt3_sub_tree_print原型
没有客户与server端连接 其打印结果为: 这是在没有任何客户端连接的情况下的订阅树,那么也就意味着这里的所有元素都是在系统子树中存在的。从最开始的“$SYS”也可以看出这其中的端倪。但是细心的你会发现在第一个"$SYS”的上面有两行空行,为什么会在最开始有两行空行呢?为了看得更清楚在源码基础上加了适当的打印信息,观察结果。 有一个订阅主题的客户连接 可以看到,实际上,前面的两行执行了两次搜索,很明显这里是在业务子树中搜索了两层后,由于这两层的主题为“”,故其打印为空。那为什么是两层呢?笔者猜测这应该和mosquitto本身实现有关。系统子树中分了两层“$SYS”,推测业务子树也是分了两层。新添加的用户订阅的新主意也是从这两层之下开始添加的。 其结果为: 可以看到,这里和前面没有客户端连接时发生了两个变化: mqtt3_db_sys_update函数,实际上,load子树的添加与否和socket连接时的一些时间参数有关。比起这个,笔者更关心的是load子树的作用是什么。1)第一行多了一个“mqtt”主题的相关信息打印(用户ID号和 qos值) 2)最后又添加了一个叫做“load”的子树(这个子树有点庞大了) 对于第一行的变化自然很好理解的,因为这是客户端自己订阅的,订阅树发现没有则自动添加,很正常。可是第二个变化,这个庞大的load子树又是从哪里出来的呢?它的作用又是什么呢?这些都不得而知。 经过源码分析发现,load子树的添加发生在mqtt3_db_sys_update函数(src/sys_tree.c)中,而这个函数又是在mosquitto_main_loop函数(src/loop.c,对消息的正确接收、维护和转发)中被循环调用。而且load子树只会在有客户端连接(无论是publish还是subscribe,不过在使用publish的时候,发现其添加load子树会有一个推迟,即publish后立即打印订阅树,load子树未被添加,但过一段时间如2秒再打印,则子树添加,而subscribe还没出现这种情况)。具体可以分析 从其topic的命名来看应该也可以看出一些端倪,但是这里出现的1min、5min、15min表示不能理解。 |
|