文章目录
前言
struct mosq_config
和 struct mosquitto
并列为mosquitto客户端源码中的核心数据结构,分别用于存储mosquitto客户端的配置信息和运行时状态和信息。在mosquitto客户端的运行过程中,struct mosq_config
存储mosquitto客户端的配置信息,其中的选项和参数决定了mosquitto客户端的行为和功能,而 struct mosquitto
则记录了客户端的运行时状态和相关信息,包括客户端的连接状态、订阅的主题、接收和发送的消息等等,以便客户端能够正确地处理和响应来自服务器的消息和事件。
与前文配置信息
struct mosq_config
结构体对象cfg定义为全局变量不同,mosquitto2.0.15采用在入口函数main的开始位置定义了一个指向struct mosquitto
的指针*mosq。本文将详细介绍这个struct mosquitto
定义的对象从动态分配内存到客户端向服务器发送第一包MQTT-CONNETC包结束的整个初始化过程。
我们可以简单地理解为,struct mosq_config
的cfg
存储mosquitto
客户端的配置信息,属于静态数据;而struct mosquitto
的mosq
指针对象指向mosquitto
客户端的运行时数据,属于动态数据。
我们在《mosquitto客户端配置参数管理(mosquitto2.0.15客户端源码分析之一)》一文中已经详细介绍了其中struct mosq_config
定义的对象cfg
的设置过程。
本文将详细介绍了mosquitto客户端对象“struct mosquitto *mosq”的初始化过程,分为上下两篇,上篇介绍对象的创建、初始化,下篇为网络参数设置和注册回调函数,为正在阅读mosquitto源码的读者提供一点参考。
1. 客户端对象创建
1.1 创建对象–mosquitto_new()函数
struct mosquitto *mosquitto_new
(const char *id, bool clean_start, void *userdata)是 Mosquitto 客户端源码中的一个函数,用于创建一个新的 struct mosquitto
结构体并初始化。
int main(int argc, char *argv[])
{
struct mosquitto *mosq = NULL;
...
mosq = mosquitto_new(cfg.id, cfg.clean_session, NULL);
...
}
函数的参数包括:
id
:客户端的 ID,类型为const char *
,调用时使用配置参数cfg.id。clean_start
:类型为bool
,调用时使用配置参数cfg.clean_session,这个参数此时为true,即客户端是以清空会话的方式连接到服务器(当设置为 false 时,客户端会尝试恢复与服务器的上一个连接状态,这是后话,不在本文讨论范围)。
bool clean_start
用于确定客户端是否以“清理会话”的模式启动。在MQTT中,客户端和服务器之间建立的连接被称为会话。会话可以保留某些信息,例如订阅的主题和发布的消息。清理会话是指当客户端与服务器重新连接时,服务器是否保留先前的会话信息。如果使用清理会话,则每次重新连接时,客户端必须重新订阅主题并重新发布任何未发布的消息。
如果clean_start
为true
,则客户端会使用清理会话模式启动,并且任何现有的会话信息都将被删除。如果为false
,则客户端会使用非清理会话模式启动,保留现有的会话信息。默认值为true
,这意味着每次客户端启动时都会删除先前的会话信息。
总之,clean_start参数的值控制着客户端启动时是否保留上一次连接断开前的状态,影响着会话信息的保留与删除。
userdata
:客户端的用户数据,类型为void *
,初始化调用时为NULL。
函数的返回值为指向 struct mosquitto
结构体的指针,赋值给mosq,如果创建失败则返回 NULL。
函数的功能包括:
-
创建一个新的
struct mosquitto
结构体,并将其初始化为默认值。 -
根据参数设置客户端的 ID、清空会话标志和用户数据。客户端的 ID 用于标识客户端,需要在 MQTT 代理中保证唯一。清空会话标志用于指示客户端是否以清空会话的方式连接到 MQTT 代理。用户数据是客户端的自定义数据,可以是任意类型的指针。
-
初始化
mosq->sock
、mosq->last_msg_in
、mosq->last_msg_out
等字段。这些字段包含了客户端的网络连接、消息缓存和心跳检测等信息。
1.2 初始化对象–mosquitto_reinitialise()函数
原型定义如下:
int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_start, void *userdata);
函数参数:
- mosq:要重新初始化的mosquitto结构体变量的指针,当前阶段指向刚刚分配内存并用默认值初始化过的对象。
- id:是调用 mosquitto_new()函数时传递的cfg.id,即客户端编号。
- clean_start:是调用 mosquitto_new()函数时传递的cfg.clean_session参数。
- userdata:是调用 mosquitto_new()函数时传递数据,目前为NULL。
该函数被mosquitto_new()在内部调用,在对象创建后,对里面的成员变量进行初始化。
...
struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata)
{
struct mosquitto *mosq = NULL;
int rc;
...
mosq = (struct mosquitto *)mosquitto__calloc(1, sizeof(struct mosquitto));
if(mosq){
...
rc = mosquitto_reinitialise(mosq, id, clean_start, userdata);
...
}else{
errno = ENOMEM;
}
return mosq;
}
...
函数返回成功时,主要对下面的成员进行了初始化(这里只列举了一部分成员变量,实际完成的初始化内容,请查阅源代码):
- mosq->use