MQTT协议理论、mosquitto库的API总结

1 MQTT协议

messge Queuing Telemetry Transport,是一种轻量级的消息传输协议

采用发布/订阅模式,包含主题(topic)、发布者(Pubisher)、订阅者(subscriber)等概念。

1.1 MQTT的通信模型和架构

通信模型:基于发布者/订阅者模式。

发布者将消息发布到MQTT代理服务器上,订阅者通过订阅相应的主题来接收消息。

**MQTT代理服务器(Broker)**是消息传递的核心,负责接收和分发消息。

如果把发送消息或接收消息的端叫做Client,那么一个Client即可以是发布者(publisher)也可以是订阅者(Subscriber)。因为一个Client可以通过publish接口发送消息,也可以通过实现subscribe接口实现订阅消息。

代理(Broker)是链接发布者(publisher)和订阅者(subscriber)的中心,一个代理可以链接上千个CLient。代理的职责是接收所有发布者的消息,判断消息应该发往那个订阅者。

1.2 MQTT的可靠性和实时性

MQTT提供三种不同的消息质等级(Qos):

**Qos0:**消息最多传输一次,不能保证消息到达。不进行任何确认和重传机制,消息可能会丢失或重复。适用于对消息丢失不敏感的场景。

**Qos1:**消息至少传输一次,可能会重复,接收者必须返回确认消息给发布者,确保消息至少被传输一次,适用于需要确保消息到达但允许重复的场景。

**Qos2:**消息只传输一次,确保消息只被传递一次,且消息不丢失,不重复。过程中进行了多次握手和确认。适用于需要严格保证消息唯一性的场景。

以实现可靠的消息传输

**支持持久性连接,**减少连接建立和关闭的频率,提高通信效率

1.3 MQTT的消息过期

消息过期时间间隔是MQTT 5.0 引入的一个新特性。

它允许 发布端为有时效性的消息设置一个过期间隔,如果该消息在服务端中停留超过了这个指定的间隔,那么服务端将不会再将它分发给订阅端。默认情况下,消息中不会包含消息过期间隔,这表示该消息永远不会过期。

MQTT 的持久性连接 可以为离线的客户端缓存尚未发送的消息,然后在客户端恢复连接时发送。

但有些消息是有时效性的

2 开发MQTT客户端的流程

  1. 选择MQTT库:根据你的开发环境和需求,选择一个合适的MQTT客户端库。有许多开源的MQTT客户端库可供选择,例如Eclipse Paho、MQTTnet等,它们支持多种编程语言。
  2. 设置MQTT Broker:在开发之前,你需要一个MQTT Broker来处理客户端的连接、消息的发布和订阅。你可以选择一个公共的Broker,如HiveMQ Cloud,或者搭建自己的Broker实例。
  3. 创建MQTT客户端实例:使用所选的MQTT库创建一个客户端实例,并设置客户端的标识符(Client ID)。
  4. 配置网络连接:配置客户端的网络连接,包括服务器地址(Server Host)、端口(Server Port)以及是否使用SSL/TLS加密连接。
  5. 设置认证信息:如果Broker需要认证,你需要提供用户名(Username)和密码(Password)。
  6. 连接到Broker:使用配置好的参数连接到MQTT Broker。
  7. 订阅主题:根据需求订阅一个或多个主题(Topics),以便接收相关的消息。
  8. 发布消息:向指定的主题发布消息,可以设置消息的服务质量(QoS)和是否保留(Retain)。
  9. 处理接收到的消息:为客户端设置一个消息接收回调函数,以便在接收到订阅主题的消息时进行处理。
  10. 断开连接:在完成消息交换后,正确地断开与Broker的连接。
  11. 错误处理和重连机制:实现错误处理逻辑和自动重连机制,以应对网络波动或Broker服务中断的情况。
  12. 测试和调试:在开发过程中,使用MQTT客户端工具(如MQTTX)进行测试和调试,确保客户端按预期工作。
  13. 部署和监控:将开发好的MQTT客户端部署到生产环境,并监控其性能和状态。

3 Mosquitto库



4. **回调函数**:
   - Mosquitto 库使用回调函数来处理如连接、消息到达等事件。你可以为这些事件设置回调函数,以便在它们发生时执行特定的操作。

5. **网络循环**:
   - `mosquitto_loop` 函数是 Mosquitto 库的核心,它处理网络事件,如发送和接收消息。你可以在主事件循环中调用这个函数,或者使用 `mosquitto_loop_start` 来在单独的线程中运行它。

6. **线程特定操作**:
   - 如果你的应用程序使用多线程,并且你需要在不同的线程中操作 Mosquitto 客户端,那么你需要确保正确地管理线程间的同步,尤其是在调用 `mosquitto_lib_init` 和 `mosquitto_lib_cleanup` 时。

在多线程环境中使用 Mosquitto 库时,确保遵循线程安全的最佳实践,避免在多个线程中同时修改共享数据,除非你使用了适当的同步机制。

需要包含头文件: mosquitto.h 是 Mosquitto 客户端库( libmosquitto )的头文件,它包含了使用该库时所需的函数和定义。这个库允许你的应用程序与 MQTT 代理进行通信,支持发布消息、订阅主题等操作。

线程安全:

除了mosquitto_lib_init函数外,libmosquitto 提供了线程安全的操作方法。这意味着在多线程环境中,你可以安全地使用库中的大部分函数,而不必担心数据竞争或一致性问题。

编写代码来初始化Mosquitto.h库、创建客户端、连接到代理、订阅主题、发布消息以及设置回调函数。

3.1 创建客户端:

3.1.1 ☆库的初始化和清理
1.mosquitto_lib_init 函数用于初始化 Mosquitto 库,必须在调用任何其他 Mosquitto 函数之前执行。这个函数不是线程安全的,因此应确保在程序的任何其他线程启动之前调用它,并且只调用一次。

    int mosquitto_lib_init(void);

    返回值:
       	MOSQ_ERR_SUCCESS	表示成功
        MOSQ_ERR_UNKNOWN	在Windows上,无法初始化套接字
示例代码:
   if(mosquitto_lib_init() != MOSQ_ERR_SUCCESS) {
     std::cerr<<"Failed to initialize Mosquitto library."<<std::endl;
     return 1;
   }

*****************************************************************************************
2.mosquitto_lib_version这个函数用于获取Mosquitto库的版本信息。这可以帮助你的应用程序在运行时检查库版本是否符合预期,从而确保兼容性。
	
	int mosquitto_lib_version(int *major, int *minor, int*revision);
	参数:
		major:用于存储库的主版本号,不需要则置为NULL
		minor:用于存储库的次版本号,不需要则置为NULL
		revision:用于将存储库的修订号,不需要则置为NULL
	返回值:
		返回一个整数,表示库的版本号。
*****************************************************************************************        
3.mosquitto_lib_cleanup 调用此函数以释放库使用的资源。这确保了所有分配的内存和其他资源都被正确清理。
        
   int mosquitto_lib_cleanup(void);     
	返回值:
		MOSQ_ERR_SUCCESS 	总是成功
3.1.2 ☆客户端实例
1.mosquitto_new 创建一个新的Mosquitto客户端实例。
    
    struct mosquitto* mosquitto_new(const char* id, bool clean_session, void* userdata);
 参数:
     id:客户端ID。如果为NULL,则生成一个随机客户端ID,且clean_session必须为true。
     clean_session:设置为true时,断开连接后,代理会清除所有消息和订阅。如果id为NULL,则此参数必须为true。
     	注意:所有消息并不包括:
     			该客户端待确认的消息
     			客户端已经传出的消息。
     userdata:用户数据,会作为回调函数的参数传递,不需要回调则置为NULL。
     
返回值:
     成功时返回指向struct mosquitto的指针;
     失败时返回NULL,可以通过检查errno来确定失败原因。(ENOMEM 内存不足 EINVAL 无效输入参数的)
         
 示例:
    #include <mosquitto.h>
	#include <stdio.h>

    int main() {
        struct mosquitto* mosq = mosquitto_new("my_client_id", true, NULL);
        if (mosq == NULL) {
            perror("Unable to create mosquitto client");
            return 1;
        }

        // 使用mosq进行操作...

        mosquitto_destroy(mosq);
        return 0;
} 
*****************************************************************************************
2. mosquitto_destroy 释放与Mosquitto客户端实例相关的内存,销毁客户端实例。
    
    void mosquitto_destroy(struct mosquitto* mosq);
	参数:
        mosq:要销毁的Mosquitto客户端实例。
        
*****************************************************************************************
3. mosquitto_reinitialise 允许重用现有的Mosquitto客户端实例。此函数允许在不释放和重新分配内存已有的该客户端实例的情况下,重用该的客户端实例。这在你需要更改客户端配置但不想失去现有连接状态时非常有用。
  
   int mosquitto_reinitialise(struct mosquitto* mosq,
       const char* id,  bool clean_session,void* userdata);
	
	参数:
        mosq:要重新初始化的Mosquitto客户端实例。
        id:新的客户端ID。如果为NULL,则生成一个随机客户端ID。
        clean_session:设置为true时,断开连接后,代理会清除所有消息和订阅。如果id为NULL,则此参数必须为true。
        userdata:新的用户数据,会作为回调函数的参数传递。
    
    返回值:
        MOSQ_ERR_SUCCESS:成功。
        MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOMEM:内存不足。

这些函数为Mosquitto客户端的生命周期管理提供了基本的操作,包括创建、销毁和重新初始化客户端实例。通过这些函数,你可以灵活地管理客户端资源,并根据需要调整客户端配置。    
       
3.1.3 设置客户端选项
1.mosquitto_int_option 用于设置客户端的整数类型选项。

int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value);

参数:
    mosq:指向struct mosquitto实例的指针。
    option:要设置的选项类型。
    value:选项的整数值。
返回值:
    MOSQ_ERR_SUCCESS:操作成功。
    MOSQ_ERR_INVAL:输入参数无效。
    
2.mosquitto_string_option 用于设置客户端的字符串类型选项。

int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value);
    参数:
        mosq:指向struct mosquitto实例的指针。
        option:要设置的选项类型。
        value:选项的字符串值。
    返回值:
        MOSQ_ERR_SUCCESS:操作成功。
        MOSQ_ERR_INVAL:输入参数无效。 
        
3.mosquitto_void_option 用于设置客户端的void指针类型选项。

int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value);

    参数:
        mosq:指向struct mosquitto实例的指针。
        option:要设置的选项类型。
        value:选项的void指针值。
    返回值:
        MOSQ_ERR_SUCCESS:操作成功。
        MOSQ_ERR_INVAL:输入参数无效。
4.mosquitto_reconnect_delay_set 控制客户端在意外断开连接时的行为。

int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff);
    参数:
        mosq:指向struct mosquitto实例的指针。
        reconnect_delay:重新连接前的初始延迟时间(秒)。
        reconnect_delay_max:重新连接的最大延迟时间(秒)。
        reconnect_exponential_backoff:是否启用指数退避策略。
    返回值:
        MOSQ_ERR_SUCCESS:操作成功。
        MOSQ_ERR_INVAL:输入参数无效。
5.mosquitto_user_data_set 设置客户端的用户数据,这些数据将作为回调函数的参数传递。

int mosquitto_user_data_set(struct mosquitto *mosq, void *userdata);

    参数:
        mosq:指向struct mosquitto实例的指针。
        userdata:用户数据指针。
    返回值:
        MOSQ_ERR_SUCCESS:操作成功。
        MOSQ_ERR_INVAL:输入参数无效。
        
6.mosquitto_userdata检索Mosquitto客户端的“userdata”变量。

void *mosquitto_userdata(struct mosquitto *mosq);

    参数:
        mosq:指向struct mosquitto实例的指针。
    返回值:
        用户数据指针。
        
这些函数提供了对Mosquitto客户端行为的细粒度控制,包括设置选项、控制重新连接策略、传递用户数据等。通过这些函数,你可以根据应用需求配置客户端,以适应不同的网络环境和应用场景。
3.1.4 struct mosquitto结构体

struct mosquitto 是 Mosquitto 客户端库中的核心结构体,它包含了 MQTT 客户端的所有状态和配置信息。以下是 struct mosquitto 的一些关键成员和它们的作用:

struct mosquitto{
        sock;//客户端使用的 socket 连接描述符。
        protocol;//客户端使用的 MQTT 协议版本。
        address;//客户端的 IP 地址。
        id;//客户端的 ID,用于唯一标识客户端。
        username 和 password;//客户端的用户名和密码,用于 ACL 鉴权。
        keepalive;//心跳间隔时间,用于保持连接的活跃状态。
        state;//客户端的当前状态。
        will;//客户端的遗嘱消息,当客户端异常断开时,Mosquitto 会代为发布此消息。
        clean_session;//清除会话标志,指示是否在连接时清除之前的会话信息。
        msgs;//客户端的消息链表,包括待发送和已发送但尚未确认的消息。
        out_packet;//待发送给客户端的报文链表。
        subs;//客户端订阅的主题链表。
};

3.2 ☆设置认证消息

在 MQTT 协议中,认证是连接握手过程的一部分,确保只有拥有有效凭据的客户端才能连接到代理并访问其服务。这是 MQTT 代理提供的安全特性之一,有助于防止未授权访问。

mosquitto_username_pw_set 函数用于为 **Mosquitto 客户端实例配置用户名和密码。这个函数必须在调用 mosquitto_connect 之前调用此函数,**以确保在连接到 MQTT 代理时能够使用这些凭据进行认证。

int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password);

    参数:
       mosq:指向struct mosquitto的指针,代表 Mosquitto 客户端实例。
       username:指向字符的指针,包含要设置的用户名。如果为NULL,则不发送用户名。
       password:指向字符的指针,包含要设置的密码。如果username为NULL,则此参数将被忽略。
    返回值:
        MOSQ_ERR_SUCCESS:函数调用成功。
       	MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOMEM:内存分配失败。
示例代码:
    // 设置用户名和密码
    int rc = mosquitto_username_pw_set(mosq, "my_username", "my_password");
    if(rc != MOSQ_ERR_SUCCESS){
        // 处理错误:无效参数或内存不足
        mosquitto_destroy(mosq);
        return 1;
    }

3.3 连接到MQTT代理服务器

3.3.1 ☆连接MQTT代理服务器
1. mosquitto_connect 连接到MQTT代理服务器。
	函数功能:
    	mosquitto_connect 是同步操作,调用这个函数时,程序会停在这一行,直到MQTT客户端与服务器的连接尝试完成(无论是成功还是失败)。使用mosquitto_loop处理网络通信,则必须使用 mosquitto_connect 连接代理服务器。
    
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
    参数:
        mosq:指向struct mosquitto实例的指针。
        host:代理服务器的ip地址或者主机名。
        port:代理服务器的网络端口,通常是1883,如果是加密连接则可能是8883。
        keepalive:客户端和代理之间保持连接的心跳间隔时间(秒),如果在这段时间内没有信息交换,代理会向客户端发送PING消息来检查客户端是否仍然连接。
    返回值:
        MOSQ_ERR_SUCCESS:连接成功。
        MOSQ_ERR_INVAL:如果输入参数无效,可以是以下任何一种:
                mosq == NULL
                host == 空
                port < 0
                keepalive < 5
        MOSQ_ERR_ERRNO:如果系统调用返回错误。变量errno包含错误代码在Linux下使用 strerror(errno)

2.mosquitto_connect_async 异步连接到MQTT代理服务器。
     函数功能:
        这个函数用于异步客户端,它不会阻塞调用线程。如果使用 mosquitto_connect_async则客户端必须使用 threaded 接口mosquitto_loop_start来处理网络通信。可以在 mosquitto_loop_start 之前或之后调用。

int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive);
    参数:
        mosq:指向struct mosquitto实例的指针。
        host:代理服务器的地址。
        port:代理服务器的端口号。
        keepalive:心跳间隔时间(秒)。
    返回值:
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_ERRNO	如果系统调用返回错误。变量errno包含错误代码在Linux下使用 strerror(errno)

其他:

1. mosquitto_connect_bind 连接到MQTT代理服务器,并绑定到特定的本地IP地址和端口。

int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, int bind_port);
    参数:
        mosq:指向struct mosquitto实例的指针。
        host:代理服务器的地址。
        port:代理服务器的端口号。
        keepalive:心跳间隔时间(秒)。
        bind_address:本地IP地址。
        bind_port:本地端口号。
    返回值:
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_ERRNO	如果系统调用返回错误。变量errno包含错误代码在Linux下使用 strerror(errno)
****************************************************************************************
2. mosquitto_connect_bind_v5 连接到MQTT代理服务器,并绑定到特定的本地IP地址和端口,支持MQTT 5.0协议。

int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, int bind_port, const mosquitto_property *properties);
    参数:
        mosq:指向struct mosquitto实例的指针。
        host:代理服务器的地址。
        port:代理服务器的端口号。
        keepalive:心跳间隔时间(秒)。
        bind_address:本地IP地址。
        bind_port:本地端口号。
        properties:指向mosquitto_property结构体的指针,包含MQTT 5.0属性。
	返回值:
       	MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_ERRNO	如果系统调用返回错误。变量errno包含错误代码在Linux下使用 strerror(errno)
*****************************************************************************************
3. mosquitto_connect_bind_async 异步连接到MQTT代理服务器,并绑定到特定的本地IP地址和端口。

int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, int bind_port);
	参数:
        mosq:指向struct mosquitto实例的指针。
        host:代理服务器的地址。
        port:代理服务器的端口号。
        keepalive:心跳间隔时间(秒)。
        bind_address:本地IP地址。
        bind_port:本地端口号。
	返回值:
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_ERRNO	如果系统调用返回错误。变量errno包含错误代码在Linux下使用 strerror(errno)
        
*****************************************************************************************
4. mosquitto_connect_srv 使用SRV记录(通常用于DNS服务发现)连接到MQTT代理服务器。(不建议使用此调用)

int mosquitto_connect_srv(struct mosquitto *mosq, const char *srv_host, int port, int keepalive);
    参数:
        mosq:指向struct mosquitto实例的指针。
        srv_host:SRV记录的主机名。
        port:代理服务器的端口号。
        keepalive:心跳间隔时间(秒)。
	返回值:
        返回int类型,表示连接操作的结果。
*****************************************************************************************
5. mosquitto_reconnect 重新连接到代理服务器。

int mosquitto_reconnect(struct mosquitto *mosq);在连接丢失后,重新连接到代理的方法。
    参数:
   		mosq:指向struct mosquitto实例的指针。
    返回值:
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_ERRNO	如果系统调用返回错误。变量errno包含错误代码在Linux下使用 strerror(errno)

*****************************************************************************************
6. mosquitto_reconnect_async 异步重新连接到代理服务器。

int mosquitto_reconnect_async(struct mosquitto *mosq);

    参数:
    	mosq:指向struct mosquitto实例的指针。
    返回值:
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_ERRNO	如果系统调用返回错误。变量errno包含错误代码在Linux下使用 strerror(errno)
3.3.2 断开与MQTT代理的连接
1. mosquitto_disconnect 断开与代理服务器的连接。

int mosquitto_disconnect(struct mosquitto *mosq);

    参数:
    	mosq:指向struct mosquitto实例的指针。
    返回值:  
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。

其他:

1. mosquitto_disconnect_v5 断开与代理服务器的连接,并附加MQTT 5.0属性。

int mosquitto_disconnect_v5(struct mosquitto *mosq,int reason_code, const mosquitto_property *properties);

    参数:
        mosq:指向struct mosquitto实例的指针。
        reason_code:断开连接的原因码
        properties:指向mosquitto_property结构体的指针,包含MQTT 5.0属性。
    返回值:
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_DUPLICATE_PROPERTY	如果属性在禁止的地方重复。
        MOSQ_ERR_PROTOCOL	如果任何属性对 DISCONNECT 无效。

    
这些函数提供了连接、重新连接和断开连接到MQTT代理服务器的能力,支持同步和异步操作,以及MQTT 5.0协议的特性。在实际应用中,你可以根据需要选择适当的函数来管理客户端的连接状态。   

3.4 ☆订阅主题和发布主题

3.4.1 ☆发布消息
1. mosquitto_publish 发布消息到代理并指定主题。

int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain);

    参数:
        mosq:指向struct mosquitto实例的指针。
        mid:指向整数的指针,如果不是NULL,函数会将它置为该条发布消息的消息ID。
        	消息ID:
        		用于跟踪Qos为1/2的消息,因为这些级别的Qos需要确保消息的传递。
        	发布回调:该函数允许设置一个publish 回调函数,以便在消息被发送时得到通知(当消息被代理服务器处理,并确认ACK时),就会调用该回调函数。
        topic:要发布消息的主题。
        payloadlen:消息有效载荷的长度。
        payload:消息有效载荷。
        qos:消息的服务质量( 0,1,或 2)。
		retain:是否设置该消息为保留消息。设置为true,则消息保留。
        	保留消息:MQTT代理会保留这个消息,即使这个消息已经被当前所有订阅者接收,任何新的订阅者在订阅这个消息的主题后,都会立即接收到这条消息,即使这条消息是在客户端订阅之前发布的。
    返回值:
        MOSQ_ERR_SUCCESS 	表示成功 
		MOSQ_ERR_INVAL:		如果输入参数无效。
        MOSQ_ERR_NOMEM:		如果发生内存不足的情况。
        MOSQ_ERR_NO_CONN:	如果客户端未连接到代理。
        MOSQ_ERR_PROTOCOL:	如果与代理通信时出现协议错误。
        MOSQ_ERR_PAYLOAD_SIZE:		如果 payloadlen 太大。
        MOSQ_ERR_MALFORMED_UTF8:	如果主题不是有效的 UTF-8
        MOSQ_ERR_QOS_NOT_SUPPORTED:	如果 QoS 大于代理所支持的。
        MOSQ_ERR_OVERSIZE_PACKET:	如果生成的数据包大于代理支持的数据包。

****************************************************************************************
2,mosquitto_publish_v5 发布消息到指定的MQTT主题,并附加MQTT 5.0属性。

int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain, const mosquitto_property *properties);
	参数:
        同上;
        properties:指向MQTT 5.0属性的指针。
    返回值:
      
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL		如果输入参数无效。
        MOSQ_ERR_NOMEM		如果发生内存不足情况。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_PROTOCOL	如果与 broker 通信时出现协议错误。
        MOSQ_ERR_PAYLOAD_SIZE	如果 payloadlen 太大。
        MOSQ_ERR_MALFORMED_UTF8	如果主题不是有效的 UTF-8
        MOSQ_ERR_DUPLICATE_PROPERTY	如果属性在禁止的地方重复。
        MOSQ_ERR_PROTOCOL	如果任何属性无法与 PUBLISH 一起使用。
        MOSQ_ERR_QOS_NOT_SUPPORTED		QoS 是否大于 broker 支持的 QoS。
        MOSQ_ERR_OVERSIZE_PACKET	如果生成的数据包大于代理支持的数据包。
  
3.4.2 ☆订阅主题
1.mosquitto_subscribe 一次订阅一个MQTT主题。

int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos);

	参数:
        mosq:指向struct mosquitto实例的指针。
        mid:指向整数的指针,如果不是NULL,函数会将它置为该订阅请求的消息ID。后续可以用于回调函数中。
        sub:要订阅的主题。
        qos:订阅的服务质量等级。 
     返回值:    
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_MALFORMED_UTF8	如果主题不是有效的 UTF-8
        MOSQ_ERR_OVERSIZE_PACKET	如果生成的数据包大于代理支持的数据包。

****************************************************************************************       
2.mosquitto_subscribe_v5订阅一个MQTT主题,并附加MQTT 5.0属性。

int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties);

	参数:
        mosq:指向struct mosquitto实例的指针.
		mid:指向整数的指针。如果不是NULL,函数会将其设置为该订阅请求的消息ID。可以用于后续的回调函数中。
        sub:这是一个指向字符指针,指向一个主题字符串。
		qos:表示所有订阅请求的服务质量(QoS)。
		options:用于指定订阅选项。这个参数通常设置为 0。
		properties:这是一个指向mosquitto_property结构体的指针,包含 MQTT 5.0 属性。这些属性可以用于设置订阅的高级参数,如用户属性等。如果不需要设置这些属性,可以置为NULL。
    返回值:
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_MALFORMED_UTF8	如果主题不是有效的 UTF-8
        MOSQ_ERR_DUPLICATE_PROPERTY	如果属性在禁止的地方重复。
        MOSQ_ERR_PROTOCOL	如果任何属性对 SUBSCRIBE 无效。
        MOSQ_ERR_OVERSIZE_PACKET	如果生成的数据包大于代理支持的数据包。
**************************************************************************************** 
3.mosquitto_subscribe_multiple 一次订阅多个MQTT主题。

int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties);

	参数:
        mosq:指向struct mosquitto实例的指针.
		mid:指向整数的指针。如果不是NULL,函数会将其设置为该订阅请求的消息ID。可以用于后续的回调函数中。
        sub_count:这是一个整数,表示要订阅的主题数量。
        sub:这是一个指向字符指针数组的指针,每个指针指向一个主题字符串。这个数组包含了所有要订阅的主题。
		qos:表示所有订阅请求的服务质量(QoS)。
		options:用于指定订阅选项。这个参数通常设置为 0。
		properties:这是一个指向mosquitto_property结构体的指针,包含 MQTT 5.0 属性。这些属性可以用于设置订阅的高级参数,如用户属性等。如果不需要设置这些属性,可以置为NULL。
	返回值:
       	MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_MALFORMED_UTF8	如果主题不是有效的 UTF-8
        MOSQ_ERR_OVERSIZE_PACKET	如果生成的数据包大于代理支持的数据包。
 
3.4.3 ☆取消订阅
1.mosquitto_unsubscribe 从MQTT代理取消订阅某主题。

int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub);
	参数:
        mosq:指向struct mosquitto实例的指针。
        mid:指向整数的指针,如果不为NULL,该函数会将其设置为此特定消息的消息ID。然后可以将其与取消订阅回调一起使用,以确定消息何时发送。
        sub:要取消订阅的主题。
    返回值:
       	MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_MALFORMED_UTF8	如果主题不是有效的 UTF-8
        MOSQ_ERR_OVERSIZE_PACKET	如果生成的数据包大于代理支持的数据包。
**************************************************************************************** 
2.mosquitto_unsubscribe_v5 从MQTT主题取消订阅,并附加MQTT 5.0属性。
 
int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties);
    参数:
        mosq:指向struct mosquitto实例的指针。
        mid:指向整数的指针,如果不为NULL,该函数会将其设置为此特定消息的消息ID。然后可以将其与取消订阅回调一起使用,以确定消息何时发送。
        sub:要取消订阅的主题。
    	properties:指向MQTT 5.0属性的指针。
	返回值:
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_MALFORMED_UTF8	如果主题不是有效的 UTF-8
        MOSQ_ERR_OVERSIZE_PACKET 如果生成的数据包大于代理支持的数据包。
****************************************************************************************
3,mosquitto_unsubscribe_multiple 从多个MQTT主题取消订阅。
 
int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties);
    
	参数:
        mosq:指向struct mosquitto实例的指针.
		mid:指向整数的指针。如果不是NULL,函数会将其设置为该取消订阅请求的消息ID。可以用于后续的回调函数中。
        sub_count:这是一个整数,表示要取消订阅的主题数量。
        sub:这是一个指向字符指针数组的指针,每个指针指向一个主题字符串。这个数组包含了所有要取消订阅的主题。
		properties:这是一个指向mosquitto_property结构体的指针,包含 MQTT 5.0 属性。这些属性可以用于设置取消订阅的高级参数,如用户属性等。如果不需要设置这些属性,可以置为NULL。
    返回值:    
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_MALFORMED_UTF8	如果主题不是有效的 UTF-8
        MOSQ_ERR_OVERSIZE_PACKET	如果生成的数据包大于代理支持的数据包。

这些函数是Mosquitto库
中用于发布和订阅MQTT主题的核心API。通过这些函数,你可以实现MQTT客户端的基本功能,包括连接、发布消息、订阅主题和取消订阅。返回值通常是整数错误码,MOSQ_ERR_SUCCESS 表示操作成功,其他值表示不同的错误情况。

3.5 处理接收到的消息

这些函数是Mosquitto库中用于处理mosquitto_message结构体的API,它们允许你复制和释放消息内容。以下是每个函数的详细说明和函数原型:

1. mosquitto_message_copy 复制一个mosquitto_message结构体的内容到另一个消息结构体中。
说明:
此函数用于将一个消息的内容复制到另一个消息结构体中。这在你需要保留消息内容的副本时非常有用,例如在异步回调处理中。
int mosquitto_message_copy(struct mosquitto_message *dest, const struct mosquitto_message *src);

    参数:
        dest:指向目标mosquitto_message结构体的指针,用于存储复制的内容。
        src:指向源mosquitto_message结构体的指针,其内容将被复制。
    返回值:
        MOSQ_ERR_SUCCESS:复制成功。
        MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOMEM:内存不足。


2. mosquitto_message_free 完全释放一个mosquitto_message结构体及其内容。
说明:
此函数用于释放mosquitto_message结构体及其内容所占用的内存。在消息不再需要时,应调用此函数以避免内存泄漏。 
void mosquitto_message_free(struct mosquitto_message *message);
    参数:
   		message:指向要释放的mosquitto_message结构体的指针。

3. mosquitto_message_free_contents 释放mosquitto_message结构体内容的内存,但不影响结构体本身。
 说明:
此函数用于释放mosquitto_message结构体中有效载荷(payload)所占用的内存,但保留结构体本身。这在你需要保留消息结构体但释放其内容时非常有用。
void mosquitto_message_free_contents(struct mosquitto_message *message);
    
	参数:
     	message:指向要释放内容的mosquitto_message结构体的指针。


示例代码:
    struct mosquitto_message *msg = malloc(sizeof(struct mosquitto_message));
    if(msg) {
        msg->payload = strdup("Hello MQTT");
        msg->payloadlen = strlen("Hello MQTT");
        // 使用消息...

        // 释放消息内容
        mosquitto_message_free_contents(msg);

        // 释放整个消息结构体
        mosquitto_message_free(msg);
    }
这些函数提供了对mosquitto_message结构体内容的管理,确保了资源的正确分配和释放。在使用这些函数时,应确保正确处理返回值和可能的错误情况。

3.6 ☆网络循环

网络循环(Network Loop)在MQTT客户端中扮演着至关重要的角色,**它负责维护客户端与MQTT代理(Broker)之间的持续连接,并处理所有的网络事件。**以下是网络循环的几个关键职责:

**Network loop (managed by libmosquitto)**内部网络循环。

必须定期调用内部网络循环。

相关API:

1. mosquitto_loop_forever,这个函数会为你调用mosquitto_loop,在无限阻塞循环中处理网络事件。它适用于你只想在程序中运行MQTT客户端循环的情况。如果服务器连接丢失,它将处理重新连接。如果在回调中调用mosquitto_disconnect(),它将返回。
 
int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets);

    参数:
        mosq:指向struct mosquitto实例的指针。
        timeout:在select()调用中等待网络活动的最大毫秒数。设置为0以立即返回,设置为负值可使用默认值(通常是1000ms)。
        max_packets:这个参数当前未使用,应设为1,以备将来使用。
	返回值:
        MOSQ_ERR_SUCCESS:成功。
        MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOMEM:内存不足。
        MOSQ_ERR_NO_CONN:客户端未连接到代理。
        MOSQ_ERR_CONN_LOST:与代理的连接丢失。
        MOSQ_ERR_PROTOCOL:与代理进行通信时存在协议错误。
        MOSQ_ERR_ERRNO:系统调用返回错误,可通过errno获取具体错误代码。
            
2. mosquitto_loop_start,这是线程客户端接口的一部分。调用此函数会创建一个新的线程,该线程不断调用mosquitto_loop()函数处理网络事件,而不阻塞主线程。
 
int mosquitto_loop_start(struct mosquitto *mosq);

    参数:
    	mosq:指向struct mosquitto实例的指针。
    返回值:
        MOSQ_ERR_SUCCESS:成功。
        MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOT_SUPPORTED:没有线程支持。
        
3. mosquitto_loop_stop,这也是线程客户端接口的一部分。调用此函数可以停止先前使用mosquitto_loop_start()创建的网络线程。该调用将一直阻塞,直到网络线程结束。为了使网络线程结束,你必须事先调用mosquitto_disconnect()。
 
int mosquitto_loop_stop(struct mosquitto *mosq, bool force);
	
	参数:
 		mosq:指向struct mosquitto实例的指针,
		force:设置为true强制取消线程。如果为false,则必须已经调用mosquitto_disconnect()。
	返回值:
        MOSQ_ERR_SUCCESS:成功。
        MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOT_SUPPORTED:没有线程支持。
            
4. mosquitto_loop 客户端的主网络循环。必须经常调用此函数,以保持 Client 端和 broker 之间的通信正常工作。这是通过 mosquitto_loop_forever 和 mosquitto_loop_start 实现的,这是处理网络循环的推荐方法。如果您愿意,您也可以使用此功能。它不能在回调中调用。这是客户端的主要网络循环函数。它处理所有的网络事件,包括发送和接收消息。通常在循环中调用此函数,以确保客户端能够响应网络变化。
 
int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets);

	参数:
        mosq:指向struct mosquitto实例的指针.
        timeout:在select()调用中等待网络活动的最大毫秒数。
        max_packets:这个参数当前未使用,应设为1,以备将来使用。
	返回值:
        MOSQ_ERR_SUCCESS:成功。
        MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOMEM:内存不足。
        MOSQ_ERR_NO_CONN:客户端未连接到代理。
        MOSQ_ERR_CONN_LOST:与代理的连接丢失。
        MOSQ_ERR_PROTOCOL:与代理进行通信时存在协议错误。
        MOSQ_ERR_ERRNO:系统调用返回错误,可通过errno获取具体错误代码。
        
这些函数提供了灵活的方式来处理MQTT客户端的网络事件,无论是在主线程中同步运行,还是在后台线程中异步运行。通过这些函数,你可以确保客户端能够及时响应网络变化,同时保持应用程序的响应性。

Network loop (for use in other event loops)相关API:

在MQTT客户端开发中,网络循环是处理网络事件的核心机制。以下是Mosquitto库中与网络循环相关的几个关键函数及其作用:

1. mosquitto_loop_read:
   执行网络读取操作。这个函数用于从网络读取数据,通常在你需要将Mosquitto的网络循环集成到你自己的select()或poll()调用中时使用。
 
int mosquitto_loop_read(struct mosquitto *mosq);
   参数:
     mosq:指向struct mosquitto实例的指针.
   返回值:
       MOSQ_ERR_SUCCESS:表示成功。
       MOSQ_ERR_INVAL	输入参数无效;
       MOSQ_ERR_NOMEM	内存不足;
       MOSQ_ERR_NO_CONN	 客户端未连接到Broker;
       MOSQ_ERR_CONN_LOST	与Broker的连接已丢失;
       MOSQ_ERR_PROTOCOL	与Broker通信时出现协议错误;
       MOSQ_ERR_ERRNO	系统调用返回错误,变量errno包含错误码;

2. mosquitto_loop_write  执行网络写入操作。这个函数用于将数据发送到网络,通常与 mosquitto_loop_read 一起使用,以处理网络的读写事件。
 
int mosquitto_loop_write(struct mosquitto *mosq);

   参数:
     mosq:指向struct mosquitto实例的指针;
  返回值:
        MOSQ_ERR_SUCCESS	表示成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NOMEM	如果发生内存不足情况。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。
        MOSQ_ERR_CONN_LOST	如果与 broker 的连接丢失。
        MOSQ_ERR_PROTOCOL	如果与 broker 通信时出现协议错误。
        MOSQ_ERR_ERRNO	如果系统调用返回错误。变量 errno 包含错误代码
3. mosquitto_loop_misc
   执行网络循环中的其他必要操作。如处理心跳(PING)消息和检查是否有需要重试的消息。这个函数用于处理除了读写之外的其他网络事件,如断开连接的检测等。

     int mosquitto_loop_misc(struct mosquitto *mosq);
 
   参数:
     mosq:指向struct mosquitto实例的指针,

   返回值:        
        MOSQ_ERR_SUCCESS	成功。
        MOSQ_ERR_INVAL	如果输入参数无效。
        MOSQ_ERR_NO_CONN	如果客户端未连接到代理。



这些函数提供了对Mosquitto客户端网络循环的精细控制,允许开发者根据自己的需要集成和定制网络事件的处理。通过这些函数,你可以确保MQTT客户端能够在各种网络条件下稳定运行,并及时响应网络变化。

这些函数是Mosquitto库提供的一些辅助函数,它们用于在特定的应用场景下与库交互。以下是每个函数的详细说明和函数原型:

1. mosquitto_socket;
返回与Mosquitto客户端实例相关联的socket句柄。这个函数在你想要将Mosquitto客户端集成到自己的事件循环(例如使用select()、poll()或epoll())中时非常有用。

int mosquitto_socket(struct mosquitto *mosq);

    **参数**:
     	mosq:指向struct mosquitto 实例的指针。
    **返回值**:
     返回与Mosquitto客户端实例相关联的socket文件描述符(在Unix系统上);

**示例代码**:
    struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);
    // 配置和连接mosq...
    int sock = mosquitto_socket(mosq);
    fd_set readfds, writefds;
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);
    FD_SET(sock, &readfds);
    FD_SET(sock, &writefds);
    // 在你的事件循环中检查socket
    if (FD_ISSET(sock, &readfds)) {
        // 读取数据
        mosquitto_loop_read(mosq, 1);
    }
    if (FD_ISSET(sock, &writefds)) {
        // 写入数据
        mosquitto_loop_write(mosq, 1);
    }


2. mosquitto_want_write
返回一个布尔值,指示是否有数据准备好写入socket。这个函数在你使用自己的事件循环并且想要优化写操作时很有用。

bool mosquitto_want_write(struct mosquitto *mosq);

    **参数**:
   		 mosq:指向struct mosquitto实例的指针。
    **返回值**:
        true:如果库希望写入socket。
        false:如果库不希望写入socket。

**示例代码**:
    if (mosquitto_want_write(mosq)) {
        // socket准备好写入数据
    }

3. mosquitto_threaded_set
告知库你的应用程序正在使用多线程,但你没有使用mosquitto_loop_start来启动网络循环。这个函数对于避免在多线程环境中出现竞态条件非常重要。

int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded);

    **参数**:
        mosq:指向struct mosquitto实例的指针。
        threaded:如果你的应用程序使用多线程,则设置为`true`。
    **返回值**:
        MOSQ_ERR_SUCCESS:操作成功。
        MOSQ_ERR_INVAL:输入参数无效。

**示例代码**:
	mosquitto_threaded_set(mosq, true);

使用这些函数,你可以更灵活地将Mosquitto客户端集成到复杂的应用环境中,例如在多线程应用程序中或者在需要精细控制网络事件处理的场景中。

3.7 配置TLS/SSL支持

这些函数是Mosquitto库提供的用于配置TLS/SSL支持的API。以下是每个函数的详细说明:

1. **mosquitto_tls_set**
   配置客户端以使用基于证书的SSL/TLS支持。
   
   **函数原型**:
   ```c
   int mosquitto_tls_set(struct mosquitto *mosq, const char *cafile, const char *capath, const char *certfile, const char *keyfile, int cert_reqs, const char *tls_version);
   ```
   **参数**:
   - `mosq`:指向`struct mosquitto`实例的指针。
   - `cafile`:CA证书文件的路径。
   - `capath`:CA证书目录的路径。
   - `certfile`:客户端证书文件的路径。
   - `keyfile`:客户端私钥文件的路径。
   - `cert_reqs`:服务器证书的验证级别。
   - `tls_version`:TLS版本。

   **返回值**:
   - `MOSQ_ERR_SUCCESS`:操作成功。
   - `MOSQ_ERR_INVAL`:输入参数无效。
   - `MOSQ_ERR_NOMEM`:内存分配失败。

2. **mosquitto_tls_insecure_set**
   配置是否验证服务器主机名在服务器证书中。
   
   **函数原型**:
   ```c
   int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool insecure);
   ```
   **参数**:
   - `mosq`:指向`struct mosquitto`实例的指针。
   - `insecure`:如果设置为`true`,则不验证服务器主机名。

   **返回值**:
   - `MOSQ_ERR_SUCCESS`:操作成功。
   - `MOSQ_ERR_INVAL`:输入参数无效。

3. **mosquitto_tls_opts_set**
   设置高级SSL/TLS选项。
   
   **函数原型**:
   ```c
   int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers);
   ```
   **参数**:
   - `mosq`:指向`struct mosquitto`实例的指针。
   - `cert_reqs`:服务器证书的验证级别。
   - `tls_version`:TLS版本。
   - `ciphers`:使用的加密套件。

   **返回值**:
   - `MOSQ_ERR_SUCCESS`:操作成功。
   - `MOSQ_ERR_INVAL`:输入参数无效。

4. **mosquitto_tls_psk_set**
   配置客户端以使用基于预共享密钥(PSK)的TLS支持。
   
   **函数原型**:
   ```c
   int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers);
   ```
   **参数**:
   - `mosq`:指向`struct mosquitto`实例的指针。
   - `psk`:预共享密钥。
   - `identity`:身份标识。
   - `ciphers`:使用的加密套件。

   **返回值**:
   - `MOSQ_ERR_SUCCESS`:操作成功。
   - `MOSQ_ERR_INVAL`:输入参数无效。
   - `MOSQ_ERR_NOMEM`:内存分配失败。

5. **mosquitto_ssl_get**
   检索用于此客户端TLS连接的SSL结构体的指针。
   
   **函数原型**:
   ```c
   SSL *mosquitto_ssl_get(struct mosquitto *mosq);
   ```
   **参数**:
   - `mosq`:指向`struct mosquitto`实例的指针。

   **返回值**:
   - 返回一个指向SSL结构体的指针,可以用于进行更高级的TLS操作。

这些函数提供了对TLS/SSL功能的细粒度控制,允许开发者在MQTT客户端中实现安全的通信。通过配置TLS,你可以确保客户端与MQTT代理之间的数据传输是加密的,从而提高系统的安全性。

3.8 设置回调函数的API

这些函数是Mosquitto库提供的用来设置回调函数API,用于在特定的事件发生时由库自动调用你提供的函数,这种方式可以让你在事件发生时执行自定义的代码,而不需要自己不断检查事件是否发生。以下是每个函数的详细说明:

1.mosquitto_connect_callback_set 用于设置mosquitto_connect回调的函数,这个回调函数会在客户端成功连接到MQTT代理时会被自动调用。在回调函数中执行连接后的操作。

void mosquitto_connect_callback_set(struct mosquitto *mosq, void *on_connect);
	参数:
        mosq:这是一个指向struct mosquitto实例的指针
		on_connect:这是一个函数指针,指向你提供的回调函数。这个函数必须接受三个参数:一个 struct mosquitto 实例的指针、一个 void 指针(用于传递用户定义的数据),以及一个整数(通常表示连接结果或错误代码)。
            
  回调函数on_connect:
   void on_connect(strut mosquitto * mosq,void *obj,int result);
          参数:
            mosq:指向触发回调的 struct mosquitto.实例的指针。
			obj:一个 void 指针,可以在设置回调时传递给 Libmosquitto,通常用于指向用户定义的数据结构。
			result:一个整数,表示连接的结果。
                如果连接成功,result 通常是 MOSQ_ERR_SUCCESS(值为 0)。如果连接失败,result 将是一个错误代码,你可以通过mosquitto_strerror 函数将其转换为可读的错误信息。  
****************************************************************************************
2.mosquitto_connect_with_flags_callback_set 设置连接回调函数,与mosquitto_connect_callback_set类似,但提供了额外的连接标志。
    
void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void * on_connect);
	参数:
        mosq:这是一个指向struct mosquitto实例的指针
		on_connect:这是一个函数指针,指向你提供的回调函数。
        
    回调函数on_connect:
        void on_connect(struct mosquitto *mosq, void *obj, int result, int flag)
        	参数:
        		mosq:指向触发回调的 struct mosquitto.实例的指针。
				obj:可以在设置回调时传递给 Libmosquitto,通常用于指向用户定义的数据结构。
				result:表示连接的结果。
                flag:连接标志,提供了一些额外的额外的选项 
                    具体选项可以搜索
****************************************************************************************
3.mosquitto_connect_v5_callback_set 设置MQTT 5.0版本的连接回调函数,提供了连接属性。

void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *));
****************************************************************************************
4.mosquitto_disconnect_callback_set 设置断开连接回调函数,当客户端断开连接时自动调用。

void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void *on_disconnect);
	
	参数:
        mosq:指向struct mosquitto 实例的指针,代表一个 MQTT 客户端。
		on_disconnect:当客户端断开连接时调用的回调函数。
     回调函数:
        on_disconnect(struct mosquitto *mosq, void *obj)
        参数:
       		mosq:指向触发回调的struct mosquitto 实例的指针.
			obj:可以在设置回调时传递给Libmosquitto,通常用于指向用户定义的数据结构
        
****************************************************************************************
5.mosquitto_disconnect_v5_callback_set设置MQTT 5.0版本的断开连接回调函数,提供了断开连接的原因代码和属性。

void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *));

****************************************************************************************
6.mosquitto_publish_callback_set 设置发布回调函数,当客户端成功发布消息时调用。

void mosquitto_publish_callback_set(struct mosquitto *mosq, void *on_publish);
	参数:
        mosq:指向struct mosquitto实例的指针,代表一个 MQTT 客户端。
		on_publish:当客户端成功发布消息时调用的回调函数。
    回调函数:
    void on_publish(struct mosquitto *mosq, void *obj, int mid);
	参数:
        mosq:指向触发回调的struct mosquitto 实例的指针.
		obj:,通常用于指向用户定义的数据结构。
		mid:消息ID,这是一个唯一的标识符,用于标识被发送的消息。这个ID与发布消息时 mosquitto_publish 函数返回的ID相同。


****************************************************************************************
7.mosquitto_publish_v5_callback_set设置MQTT 5.0版本的发布回调函数,提供了发布属性。

void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *));
****************************************************************************************
8.mosquitto_message_callback_set 设置消息回调函数,当客户端接收到消息时调用。

void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *));
	参数:
        mosq:指向struct mosquitto 实例的指针,代表一个 MQTT 客户端。
        on_message:当客户端接收到消息时调用的回调函数。
         
	回调函数:
void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message);
		参数:
            mosq:指向触发回调的struct mosquitto 实例的指针。
			obj:一个 void 指针,可以在设置回调时传递给 Libmosquitto,通常用于指向用户定义的数据结构。
			message:一个指向struct mosquitto_message 结构体的指针,包含了接收到的消息的详细信息,如主题、有效载荷、服务质量(QoS)等。

****************************************************************************************
9.mosquitto_message_v5_callback_set 设置MQTT 5.0版本的接收消息回调函数,提供了接收到的消息属性。

void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *));
****************************************************************************************
10.mosquitto_subscribe_callback_set 设置订阅的回调函数,当客户端成功订阅主题时调用。

void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int));
	参数:
       mosq:指向struct mosquitto 实例的指针,代表一个 MQTT 客户端。
	   on_subscribe:当客户端成功订阅主题时调用的回调函数 
    回调函数:
void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos);        
        参数:
            mosq:指向触发回调的struct mosquitto 实例的指针。
			obj:一个 void 指针,可以在设置回调时传递给 Libmosquitto,通常用于指向用户定义的数据结构。
			mid:订阅消息的 ID,用于标识订阅请求。
			qos_count:授予的 QoS 等级的数量。
			granted_qos:一个整数数组,包含了每个订阅主题的授予的 QoS 等级
                
****************************************************************************************
11.mosquitto_subscribe_v5_callback_set设置MQTT 5.0版本的订阅回调函数,提供了订阅属性。

void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const mosquitto_property *));
****************************************************************************************
12.mosquitto_unsubscribe_callback_set 设置取消订阅的回调函数,当客户端成功取消订阅主题时自动调用。

void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int));
	参数:
		mosq:指向struct mosquitto 实例的指针。
		on_unsubscribe:当客户端成功取消订阅主题时调用的回调函数。
        回调函数:
 void on_unsubscribe(struct mosquitto *mosq, void *obj, int mid);
       参数:
        mosq:指向触发回调的struct mosquitto 实例的指针。
		obj:可以在设置回调时传递给 Libmosquitto,通常用于指向用户定义的数据结构。
		mid:取消订阅操作的消息ID,这是一个唯一的标识符,用于标识取消订阅请求。	
           
****************************************************************************************
13.mosquitto_unsubscribe_v5_callback_set 设置MQTT 5.0版本的取消订阅回调函数,提供了取消订阅属性。

void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *));
****************************************************************************************
14.mosquitto_log_callback_set 设置日志回调函数,用于自定义日志消息的处理方式。

void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *));

这些回调函数为用户提供了在特定事件发生时执行自定义逻辑的能力,例如处理连接和断开事件、发布和接收消息、订阅和取消订阅事件,以及日志记录。通过设置这些回调函数,用户可以在事件发生时立即响应,从而实现更复杂的业务逻辑和错误处理。

遗嘱(Will)消息

它允许客户端在异常断开连接时(比如由于崩溃或网络问题),向服务器发送一条预先定义的消息。这样,服务器和其他客户端可以知道这个客户端已经“死亡”,并采取相应的行动。

相关的函数:

1. mosquitto_will_set 配置Mosquitto实例的遗嘱信息。
int mosquitto_will_set( struct mosquitto *mosq, 
                       const char *topic, 
                       int payloadlen, const void *payload, 
                       int qos, bool retain );
    参数:
        mosq:指向Mosquitto客户端实例的指针。
        topic:遗嘱消息要发布到的主题。
        payloadlen:遗嘱消息有效载荷的长度。
        payload:遗嘱消息的有效载荷。
        qos:遗嘱消息的服务质量(QoS)等级。
        retain:是否保留遗嘱消息。
        
    返回值:
        MOSQ_ERR_SUCCESS:成功。
        MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOMEM:内存不足。
  	
示例:
 
    int rc = mosquitto_will_set(mosq, "test/will", 7, "will msg", 1, true);
    if(rc == MOSQ_ERR_SUCCESS) {
        // 设置遗嘱成功
    } else {
        // 处理错误
    }
2. mosquitto_will_set_v5 配置Mosquitto实例的遗嘱信息,并附加MQTT 5.0属性。
    int mosquitto_will_set_v5(struct mosquitto *mosq,
                              const char *topic, 
                              int payloadlen,
                              const void *payload,
                              int qos, bool retain,
                              const mosquitto_property *properties);

    参数:
        mosq:指向Mosquitto客户端实例的指针。
        topic:遗嘱消息要发布到的主题。
        payloadlen:遗嘱消息有效载荷的长度。
        payload:遗嘱消息的有效载荷。
        qos:遗嘱消息的服务质量(QoS)等级。
        retain:是否保留遗嘱消息。
        properties:指向遗嘱消息属性的指针。
    返回值:
        MOSQ_ERR_SUCCESS:成功。
        MOSQ_ERR_INVAL:输入参数无效。
        MOSQ_ERR_NOMEM:内存不足。
示例代码:
    mosquitto_property props;
    mosquitto_property_username_set(&props, "user");
    int rc = mosquitto_will_set_v5(mosq, "test/will", 7, "will msg", 1, true, &props);
    if(rc == MOSQ_ERR_SUCCESS) {
        // 设置遗嘱成功
    } else {
        // 处理错误
    }
3. mosquitto_will_clear 移除之前配置的遗嘱信息。
    int mosquitto_will_clear(struct mosquitto *mosq);
    
	参数:
   		 mosq:指向Mosquitto客户端实例的指针。
    返回值:
        MOSQ_ERR_SUCCESS:成功。
        MOSQ_ERR_INVAL:输入参数无效。
示例代码:
    int rc = mosquitto_will_clear(mosq);
    if(rc == MOSQ_ERR_SUCCESS) {
        // 清除遗嘱成功
    } else {
        // 处理错误
    }
这些函数允许你在Mosquitto客户端实例上设置、更新或清除遗嘱消息。遗嘱消息在客户端异常断开连接时由服务器代为发布,确保系统中的其他部分可以响应客户端的“死亡”。

Eclipse Paho C++ Client库 API文档:

1、mqtt::async_client 类参考:

轻量级客户端async_client类提供了一个非阻塞的MQTT客户端,允许异步操作。以下是async_client类的一些关键API及其使用方法:

public成员:

创建一个MQTT客户端实例

构造函数:

1、async_client(const string &serverURI, 
				const string &clientId,
				const string &persistDir)
	创建可用于与MQTT服务器通信的客户端,在指定目录中使用基于文件的持久性
	参数:
	const string &serverURI:要连接到的服务器的地址,指定为URL。
	const string &clientId:在所连接的服务器上唯一的客户端标识符
	const string &persistDir:用于持久化数据的目录
React Hooks 是 React 16.8 中新增的特性,它可以让你在函数组件中使用 state、生命周期钩子等 React 特性。使用 Hooks 可以让你写出更简洁、可复用且易于测试的代码。 React Hooks 提供了一系列的 Hook 函数,包括 useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useImperativeHandle、useLayoutEffect 和 useDebugValue。每个 Hook 都有特定的用途,可以帮助你处理不同的问题。 下面是 React Hooks 的一些常用 Hook 函数: 1. useState useState 是最常用的 Hook 之一,它可以让你在函数组件中使用 state。useState 接受一个初始状态值,并返回一个数组,数组的第一个值是当前 state 值,第二个值是更新 state 值的函数。 ``` const [count, setCount] = useState(0); ``` 2. useEffect useEffect 可以让你在组件渲染后执行一些副作用操作,比如订阅事件、异步请求数据等。useEffect 接受两个参数,第一个参数是一个回调函数,第二个参数是一个数组,用于控制 useEffect 的执行时机。 ``` useEffect(() => { // 这里可以执行副作用操作 }, [dependencies]); ``` 3. useContext useContext 可以让你在组件树中获取 context 的值。它接受一个 context 对象,并返回该 context 的当前值。 ``` const value = useContext(MyContext); ``` 4. useRef useRef 可以让你在组件之间共享一个可变的引用。它返回一个对象,该对象的 current 属性可以存储任何值,并在组件的生命周期中保持不变。 ``` const ref = useRef(initialValue); ref.current = value; ``` 5. useCallback useCallback 可以让你缓存一个函数,以避免在每次渲染时都创建一个新的函数实例。它接受一个回调函数和一个依赖数组,并返回一个 memoized 的回调函数。 ``` const memoizedCallback = useCallback(() => { // 这里是回调函数的逻辑 }, [dependencies]); ``` 6. useMemo useMemo 可以让你缓存一个计算结果,以避免在每次渲染时都重新计算。它接受一个计算函数和一个依赖数组,并返回一个 memoized 的计算结果。 ``` const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); ``` 以上就是 React Hooks 的一些常用 Hook 函数,它们可以帮助你更好地处理组件状态、副作用、上下文和性能优化等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值