大家好,今天小白给大家简单的介绍下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__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相关的一些数据结构,旨在方便理解源码,欢迎一起学习交流。