1. 首页
  2. 网络技术
  3. 网络基础
  4. mosquitto源码分析

mosquitto源码分析

上传者: 2020-07-29 11:06:18上传 PDF文件 580.43KB 热度 26次
mosquitto是一款实现了消息推送协议MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,例如现在应用广泛的低功耗传感器,手机、嵌入式计算机、微型控制器等移动设备。 Mosquitto采用出版/订阅的模式实现MQTT协议,这种设计模式将通信终端之间的关系统一到服务程序中进行管理,可极大减轻客户端的开发和维护工作。13、 MosquitoMosquito源码目录结构介绍。mosquitto-1.2I----clientxanr--temperature_conversionI----installer-libmosquittomosquito. confto pulmosquito subnosquitto-tI---misccurrentcost---securitynonitsyscan--db dumJ----brokerlib--cpp- pythonmoca所需关注的日录有/ mosquito-1.2/src、/ mosquito-1.2ib、/ mosquito-1.2 client三个日录,其中src和lib日录下主要放置 mosquito的实现代码以及部分底层与网络相关的操作, client目录主要为两个客户端程序的实现源码。Mosquito的源码及其相关文档可从其官方网站获取,其官方网鲔为:htp:/ mosquito.orgmosquito客尸端和服务器运行命令发布者客户端运行命令示例mosquito pub-h 192 168.6.243-p 1883-t111-mthis is jason. hou-u111-P1l1[21订阅者客户端运行命令小例'mosquito sub-h 192 168.6.243-i111-p1883-t111-k60-d-c-uhix-Phix31 mosquito服务器端运行命令示例:/mosquitoMosquito的数据结构1)struct mosquitoi杓体 struct mosquito主要用于保存一个客户端连接的所有信息,例如用户名、密码、用户I、向该客户端发送的浩息等,其定义为:truct mosquito iint sock.charaddresscharusermamcchar° passwduint16 keepalive:time tlast msg intime tlast msg out;truct mosquito client msg"msgs上面列举了该结杓体部分重要成员,其中sok表示 mosquito服务器程序与该客户端连接通信所用的 socket描迟符; address表示该客户端的P地址;id是该客户端登陆 mosquito程序时所提供的D值,该值与其他的客户端不能重复;成员 username和password用于记录客户端登陆时所提供的用户名和密码: keepalive是该客户端需在此时间内向 mosquito服务器程序发送一条ping pong消息。参数 last msg in和 last msg out用于记录上次收发消息的时间;参数 struct mosquito client msg*msgs用于暂存储发往该 context的消息2) struct mosquito db结构体 struct mosquito db是 mosquito对所有内部数据的统一管理结构,可以认为是其内部的一个内存数据库。它保存了所有的客户端,所有客户端的订阅关系等等,其定义形式为:quito dbidbid tlast db idstruct mosquito subhier subsstruct mosquuttocontextsstruct clientid index hash *clientid index hasintcontext count:structmosquitto msg store *msg storeintmsg-store_count;structmqtt3 contig config,intsubscription count上述结构体声明中,结构体成员 struct mosquito subhier subs保存了订阅树的总树根, mosquito中对所有的topc都在该订阅树中维护,客户端的订阅关系也在该订阅树中维护;结构体成员 struct mosquito** contexts可理解为一个用于存放所有各户端变量(类型为 struct mosquIto)地址的数组, mosquito程序中,所有的客尸端都在比数组中保存:成员 Int context count用于保存数组 contexts的大小,该值也是当前 mosquito序中维持的所有客户端的数目;成员绐构体 structlientid index hash* clientid index hash用于保存一个hash表,该hash表可進过客尸端的D快速找到该客户端在数组 contexts中的索引;结构体成员 struct mqtt3 config" config用于保存 mosquito的所有配置信息3)struct mosquito subhier效据结构 struct mosquito subhier是用于保存订阅树的节点(包指叶子节点和中间节点), mosquito中对订阅树采用孩子兄弟链表法的方式进行存储,该存储方式主要借助与数据结构 struct mosquito subhier来完成,该数据结构的定义为:struct mosquito subhier tstruct mosquito subhier*children;nIcr mosquito subhier nextstruct mosquito subleaf*subsstructmosquitto msg store retained;成员说明children:该成员指针指向同结构的第一个孩子节点;next:该成员指针指向该节点的下一个弟节点sbs:该成员指向订阅列表topIc:该节点对应的 topic片段;4) struct mosquito subleaf在 mosqutto程序中,对某一 topic的所有订阅者被组织成一个订阅列表,该订阅列表是一个双向链表,链表的每个节点都保存有一个订阅者,该链表的节点即是; struct mosquito sublet,定义形式为:tructsquitto subletstruct mosquito subleaf prevtruct mosquito subleaf *nextstructmosquitto*context其中成员 struct mosquito*context表示一个订阅客户端,prev和next表示其前一个节点和后一个节点。5) structmgtt3 config结构体 struct mqtt3 config用于保存 mosquito的所有配置信息, mosquito程序在启动时将初始化该结构体并从配置文件中读取配置信恳俣存于该结构体变量内。三、 Mosquito的核心功能分析31、订阅树Mosquito i过订阅树的方式来管尹所有的 topIc以及客户端的订阅关系,它首先将所有的topi泼照分割并组织成一棵树结购,从根节点到树中的每个节点即组成该节点所对应的一个 topic,每个 topic都保存一个订阅列表,该订阅列表中保存了所有订阅当前 topIc的客户端信息。例如有如下订关系客户端a1,a2,a3订阋了 topIc:A1/B1C1客户端b,b2订阅了 topIc:A2/B2/C2客尸端c1,c2订阅∫ topIc:A1/B1C3客户端d订阅了 topIc:A2/3则在 mosquito程序中需要先将topi按照进行分割,然后将分割后的tpic片段组织成订阅树,上述订阅树的示意图为图3-1根节点A2BB2CI)C2阅说树示意图Mosquito程序在实现中根据 topIc消息的性质将订阅树分为两颗子树:业务子树和系统子树; mosquito序中将 topIc分为两种类型来处理:系统opic和业务 topic,前老主要用于发布和维护 mosquito内部的系统消息,后老的 topIc是用户订阅的业务 topIc做这和区分的原因是因为这两种的类型的 topic性质和实现方式上有许多差别,这种差别主要体现在以下4点:1)生存周期不同,系统topc无论是否有用户订阅都会存在与订阅树中,而业务 topic必须有客户端订阅才能存在(除丰其消息字段 retain设置为1)2)创建方式不同,系统 topIc在消息发布时进行创建,业务 topic即可以在订阅时创建也可以在消息发布时创建(此时需要该消息 retain宇段设置为1)3)消息保存方式不同,凡是发布到系统 topIc的消总都会被保存卜来,业务消息将直接挂到订阅列表的各 context的消息队列中,如果没有连接订阅或未设置其 retain字段,消息将不会被保存下来消息的 retain字段是否被设置在函数mqt3 handle publish进行检查,在该函数中有如下代码:retain=(header Oxon)该代码可圾消息头部的第一个bit何,在mqt3.1协议中,该为用于表示消息的类舉是否为 retain。订阅树在程序中的采用孩子一兄弟链表法来表小。其主要涉及的数据结构是:struct mosquito subhierstruct mosquito subleaf311、订阅树的搭建1、创建订阅树mosquito程序启动时将创建订阅树,该过程将创建三个节点:诃阍树总根节点、业务子树艰市点和系统子树根节,这两个子树根节点作为订阅树总根节点的两个子节点,其中订阅树总根节点和业务子树的根节点中 topic成员的恒为空字符串,而系统子树根节点中保存的值为$SYS”,如图3-2所示。「订阅树总树根节点「亚务子树1系统子树根节点根节点N8Ysmx图3-2订阅树的创建订阅树的创建土要在文件 database.c中mqt3 db open函数里实现。订阅树中节点的数据结构为 struct mosquito_ subhier订阅树采用“孩子一兄弟”链表法保存2、搭建订阅树在订阅树中,系统子树与业务子树的搭建过煋不一样,系统子树是在系统消息发布时创建,而业务子树创建过程即可以在消息发布时创建也可以在客户端订侻时才剑建。1)系统了树搭建过程Mosquito中,系统子树在发布系统消息时,自动检测 topic片段是否存布,如果不存在则在系统 topic⊥创建节点以搭建订阅树例如, mosquito程序启动时,将首先向系统 topic:$sYS/ roker/version发送一条版本消息" mosquittoversion1.2”,此时订阅树的系统了树只有个根节点,如图32所示,其搭建过程如下:(1)将 topic按照"分成topc片段,系统 Topic:$SYS/ broker/version将被分割为ssYs、 broker、 version三部分(2)根据第一个 topic片段$sYS"遍历订阋树的子节点找到系统子树的根节点(3根据 topIc下一个片段" broker查找系统子树;此时系统子树中不存在topc片段" broker”的节点,则为订阅树产生一个节点,其数据结构为: struct mosquito subhier。此时订翊树由图3-2变为图3-3所示丁阅树总树根节点「亚务子树1系统子树根节点根节点P SYShttpbrokerscsdnnet/houjixin图33添加 broker节之后的订阅对上述过在函数mqt3_ db messages_ queue中请用函数_ sub add来完成(4)依此处理 topic剩下的片段,在系统子树中添加 topic片段 version",该过程通过递归调用函数 sub add来完成。添加完ersion"片段之后的订阅树如图34所示。
下载地址
用户评论
码姐姐匿名网友 2020-07-29 11:06:20

分析的很好。

码姐姐匿名网友 2020-07-29 11:06:21

还行啊,能够运行

码姐姐匿名网友 2020-07-29 11:06:23

以为是java的,想错了,不过还是很有用,谢谢分享