Mosquitto源码中的数据结构

大家好,今天小白给大家简单的介绍下Mosquitto源码中的几个重要的数据结构,以便于理解Mosquitto源码,欢迎一起交流学习。

一、mosquitto_db

struct mosquitto_db{
    .....
    struct mosquitto__subhier *subs;                       //主题树根节点
    struct mosquitto__unpwd *unpwd;
    struct mosquitto__unpwd *psk_id;             
    struct mosquitto *contexts_by_id;                      //根据此变量遍历哈希表
    struct mosquitto *contexts_by_sock;                 //根据此变量遍历哈希表(两种遍历方式在源码中均有使用)
    struct mosquitto *contexts_for_free;                  //根据此变量找到待释放的客户端
    struct clientid__index_hash *clientid_index_hash;
    struct mosquitto_msg_store *msg_store;           //存放消息的链表
    struct mosquitto_msg_store_load *msg_store_load;
    int msg_store_count;                                          //消息数目
    unsigned long msg_store_bytes;
    char *config_file;                                                //配置文件指针
    struct mosquitto__config *config;                       //服务端配置相关的变量
    int auth_plugin_count;                                        //认证插件数目
    bool verbose;
    int persistence_changes;
    struct mosquitto *ll_for_free;                             //断开时需要释放的客户端对象链表

    ....
};

该结构体变量维护了主题树的根节点,客户端的索引,消息链表,服务端的配置等信息。

二、mosquitto__subhier

struct mosquitto__subhier {
    UT_hash_handle hh;                                          //哈希表的一个表项;(其key成员里面存放了订阅的主题)
    struct mosquitto__subhier *parent;                    //主题树结点的父结点
    struct mosquitto__subhier *children;                  //主题树结点的子结点
    struct mosquitto__subleaf *subs;                       //订阅客户端链表
    struct mosquitto_msg_store *retained;              //保留消息链表
    mosquitto__topic_element_uhpa topic;             //主题成员
    uint16_t topic_len;                                             //主题长度                                     
}; 

该变量主要是维护了主题树,订阅客户端,以及订阅主题的存放位置(哈希表)。

三、哈希表相关的结构体

3.1 UT_hash_handle

typedef struct UT_hash_handle {
   struct UT_hash_table *tbl;
   void *prev;                       /* prev element in app order      */
   void *next;                       /* next element in app order      */
   struct UT_hash_handle *hh_prev;   /* previous hh in bucket order    */
   struct UT_hash_handle *hh_next;   /* next hh in bucket order        */
   void *key;                        /* ptr to enclosing struct's key  */
   unsigned keylen;                  /* enclosing struct's key len     */
   unsigned hashv;                   /* result of hash-fcn(key)        */
} UT_hash_handle;

3.2 UT_hash_table

typedef struct UT_hash_table {
   UT_hash_bucket *buckets;                     //该成员中又存放了UT_hash_handle链表的头结点。
   unsigned num_buckets, log2_num_buckets;
   unsigned num_items;
   struct UT_hash_handle *tail; /* tail hh in app order, for fast append    */
   ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
   unsigned ideal_chain_maxlen;
   unsigned nonideal_items;
   unsigned ineff_expands, noexpand;

} UT_hash_table;

3.3 UT_hash_bucket

typedef struct UT_hash_bucket {
   struct UT_hash_handle *hh_head;       //UT_hash_handle链表的头结点;
   unsigned count;
   unsigned expand_mult;

} UT_hash_bucket;

以上三个成员的关系,可以由以下图给出:

                         Mosquitto源码中的数据结构                   

四、mosquitto__subleaf 

struct mosquitto__subleaf {
    struct mosquitto__subleaf *prev;                           //订阅链表前驱
    struct mosquitto__subleaf *next;                           //订阅链表后继
    struct mosquitto *context;                                     //订阅者对象
    int qos;                                                                  //订阅的服务质量等级
};

该变量维护了一条双向的订阅链表。

五、mosquitto_msg_store

struct mosquitto_msg_store{
    struct mosquitto_msg_store *next;                          //消息链表前驱
    struct mosquitto_msg_store *prev;                         //消息链表后继
    dbid_t db_id;
    char *source_id;                                                     //消息源id(消息来自哪个客户端)
    char *source_username;                                        //消息的用户名
    struct mosquitto__listener *source_listener;
    char **dest_ids;                                                      //消息目的id(消息应该发往哪个客户端)
    int dest_id_count;                                                   //消息被发送的目的id的数目
    int ref_count;                                                           //消息的引用次数
    char* topic;                                                              //消息主题                                      
    mosquitto__payload_uhpa payload;                       //消息负载
    uint32_t payloadlen;                                                //消息长度
    uint16_t source_mid;
    uint16_t mid;
    uint8_t qos;                                                             //消息发布的qos
    bool retain;                                                              //是否保留该消息
};

该结构体主要是维护了一个消息发布的双向链表。

六、mosquitto

struct mosquitto{

    mosq_sock_t sock;                                                //连接套接字

    enum mosquitto__protocol protocol;                      //客户端使用的协议版本号
    char *address;                                                        //客户端ip
    char *id;                                                                  //客户端id
    char *username;                                                     //客户端的用户名
    char *password;                                                      //客户端密码            (安全认证时使用)
    uint16_t keepalive;                                                  //保活时间
    uint16_t last_mid;
    enum mosquitto_client_state state;                        //客户端的状态
    time_t last_msg_in;                                                 //收到的上一条消息的时间
    time_t next_msg_out;                                              //下一条待发送的消息的时间
    time_t ping_t;                                                           //发送ping request的时间间隔
    struct mosquitto__packet  in_packet;                      //收到的报文
    struct mosquitto__packet *out_packet;                    //发送报文链表
    struct mosquitto_message *will;                              //遗嘱消息链表

    struct mosquitto_message_all *in_messages;                //收到的消息链表
    struct mosquitto_message_all *out_messages;              //发送的消息链表

    .....

}

该结构体是客户端连接句柄,存放着客户端的基本信息,以及消息和报文链表。

七、总结

本篇主要简单介绍了Mosquitto相关的一些数据结构,旨在方便理解源码,欢迎一起学习交流。

上一篇:八,论文研读


下一篇:thickbox 应用