/********************************************************************************
* 版权所有 (c) 2009, 2025 IBM Corp.、Ian Craggs 及其他
*
* 保留所有权利。本程序及其随附材料
* 根据 Eclipse 公共许可证 v2.0 的条款提供
* 以及随附的 Eclipse 分发许可证 v1.0。
*
* Eclipse 公共许可证可在以下网址获取:
* https://www.eclipse.org/legal/epl-2.0/
* Eclipse 分发许可证可在以下网址获取:
* http://www.eclipse.org/org/documents/edl-v10.php。
*
* 贡献者:
* Ian Craggs - 初始 API 和实现
* Ian Craggs、Allan Stockdill-Mander - SSL 连接
* Ian Craggs - 多服务器连接支持
* Ian Craggs - MQTT 3.1.1 支持
* Ian Craggs - 修复 bug 444103 - 未调用成功/失败回调
* Ian Craggs - 自动重连和离线缓冲(断开连接时发送)
* Ian Craggs - 二进制遗嘱消息
* Ian Craggs - 二进制密码
* Ian Craggs - 移除 eyecatchers 上的 const #168
* Ian Craggs - MQTT 5.0
***********************************************************************************/
////////////////////////////////////////////////////////////////////////////////////
/**
* @cond MQTTAsync_main
* @mainpage C 语言异步 MQTT 客户端库 (MQTTAsync)
*
* © 版权所有 2009, 2025 IBM Corp.,Ian Craggs 等。
*
* @brief C 语言异步 MQTT 客户端库。
*
* 版本 1.3.14
*
* MQTT 客户端应用程序连接到支持 MQTT 的服务器。
* 典型的客户端负责从遥测设备收集信息并将信息发布到服务器。
* 它还可以订阅主题、接收消息并使用这些信息来控制遥测设备。
*
* MQTT 客户端实现了已发布的 MQTT v3 协议。
* 您可以选择编程语言和平台编写自己的 MQTT 协议 API,但这可能非常耗时且容易出错。
*
* 为了简化 MQTT 客户端应用程序的编写,此库为您封装了
* MQTT v3 协议。使用此库,您只需几行代码即可编写一个功能齐全的
* MQTT 客户端应用程序。
* 此处提供的信息记录了异步 MQTT 客户端库(适用于 C 语言)提供的 API。
*
* 使用客户端
* 使用客户端库的应用程序通常使用类似的结构:
* 创建客户端对象
* 设置连接到 MQTT 服务器的选项
* 设置回调函数
* 将客户端连接到 MQTT 服务器
* 订阅客户端需要接收的任何主题
* 重复直至完成:
* 发布客户端需要接收的任何消息
* 处理所有传入消息
* 断开客户端连接
* 释放客户端正在使用的任何内存
* 以下显示一些简单示例:
* @ref publish
* @ref subscribe
* 以下是一些重要概念的补充信息:
* @ref async
* @ref wildcard
* @ref qos
* @ref tracing
* @ref auto_reconnect
* @ref offline_publish
* @ref HTTP_proxies
* @endcond
*/
//返回码:无错误。表示 MQTT 客户端操作成功完成。
#define MQTTASYNC_SUCCESS 0
//返回代码:指示 MQTT 客户端操作失败的通用错误代码。
#define MQTTASYNC_FAILURE -1
//错误代码 -2
#define MQTTASYNC_PERSISTENCE_ERROR -2
//客户端已断开连接。
#define MQTTASYNC_DISCONNECTED -3
/** 返回代码:已达到允许同时传输的最大消息数量。
* 已达到允许同时传输的最大消息数量。
*/
#define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4
/**返回代码:检测到无效的 UTF-8 字符串。
*/
#define MQTTASYNC_BAD_UTF8_STRING -5
/**返回代码:当该参数无效时,提供一个 NULL 参数。
*/
#define MQTTASYNC_NULL_PARAMETER -6
/**返回代码:主题已被截断(主题字符串包含嵌入的 NULL 字符)。字符串函数将无法访问完整主题。
* 使用主题长度值访问完整主题。
*/
#define MQTTASYNC_TOPICNAME_TRUNCATED -7
/**返回代码:结构体参数缺少正确的醒目标记和版本号。
*/
#define MQTTASYNC_BAD_STRUCTURE -8
/**返回代码:qos 参数不为 0、1 或 2
*/
#define MQTTASYNC_BAD_QOS -9
/**返回代码:所有 65535 个 MQTT msgid 均正在使用
*/
#define MQTTASYNC_NO_MORE_MSGIDS -10
/**返回代码:请求未完成时被丢弃
*/
#define MQTTASYNC_OPERATION_INCOMPLETE -11
/**返回代码:无法缓冲更多消息
*/
#define MQTTASYNC_MAX_BUFFERED_MESSAGES -12
/**返回代码:尝试使用非 SSL 版本的库建立 SSL 连接
*/
#define MQTTASYNC_SSL_NOT_SUPPORTED -13
/**返回代码:serverURI 中的协议前缀应为:
* @li @em tcp:// 或 @em mqtt:// - 不安全的 TCP
* @li @em ssl:// 或 @em mqtts:// - 加密 SSL/TLS
* @li @em ws:// - 不安全的 WebSocket
* @li @em wss:// - 安全的 WebSocket
*
* 启用 TLS 的前缀(ssl、mqtts、wss)仅在链接了 TLS 版本的库时有效。
*/
#define MQTTASYNC_BAD_PROTOCOL -14
/**返回代码:请勿使用其他版本 MQTT 的选项
*/
#define MQTTASYNC_BAD_MQTT_OPTION -15
/**返回代码:调用不适用于客户端的 MQTT 版本
*/
#define MQTTASYNC_WRONG_MQTT_VERSION -16
/**返回代码:0长度将主题
*/
#define MQTTASYNC_0_LEN_WILL_TOPIC -17
/*返回代码:连接或断开连接命令被忽略,因为列表头部已有一个连接或断开连接命令正在等待处理。
* 请使用 onSuccess/onFailure 回调等待上一个连接或断开连接命令完成。
*/
#define MQTTASYNC_COMMAND_IGNORED -18
/*返回代码:连接选项中的 maxBufferedMessages 必须 >= 0
*/
#define MQTTASYNC_MAX_BUFFERED -19
/**默认连接的 MQTT 版本。使用 3.1.1 后可回退到 3.1
*/
#define MQTTVERSION_DEFAULT 0
/**连接的 MQTT 版本:3.1
*/
#define MQTTVERSION_3_1 3
/**
* 连接的 MQTT 版本:3.1.1
*/
#define MQTTVERSION_3_1_1 4
/**
* 连接的 MQTT 版本: 5
*/
#define MQTTVERSION_5 5
/**
* 订阅返回的错误代码,如 3.1.1 规范中所定义
*/
#define MQTT_BAD_SUBSCRIBE 0x80
/**
* 初始化选项
*/
typedef struct
{
/** 此结构的醒目部分。必须是 MQTG。*/
char struct_id[4];
/** 此结构的版本号。必须为 0 */
int struct_version;
/** 1 = 我们执行 openssl init,0 = 将其留给应用程序 */
int do_openssl_init;
} MQTTAsync_init_options;
#define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 }
/**MQTT 库的全局初始化。程序启动时调用一次即可设置全局行为。
* handle_openssl_init - MQTT 库是否应该处理 OpenSSL 初始化 (1) 或依赖调用者在使用 MQTT 之前初始化 (0)
*/
LIBMQTT_API void MQTTAsync_global_init(MQTTAsync_init_options* inits);
/**表示 MQTT 客户端的句柄。成功调用 MQTTAsync_create() 后,将获得一个有效的客户端句柄。
*
*/
typedef void* MQTTAsync;
/**
* 表示 MQTT 消息的值。消息发布后,会向
* 客户端应用程序返回一个令牌。然后,该令牌可用于
* 检查消息是否已成功送达目的地(参见
* MQTTAsync_publish()、MQTTAsync_publishMessage()、
* MQTTAsync_deliveryComplete() 和 MQTTAsync_getPendingTokens())
*/
typedef int MQTTAsync_token;
/**表示 MQTT 消息的有效负载和属性的结构体。
* 消息主题不属于此结构体(请参阅 MQTTAsync_publishMessage()、
* MQTTAsync_publish()、MQTTAsync_receive()、MQTTAsync_freeMessage()
* 和 MQTTAsync_messageArrived())。
*/
typedef struct
{
/** 这个结构的亮点一定是 MQTM。 */
char struct_id[4];
/** 此结构的版本号。必须为 0 或 1。
* 0 表示没有消息属性 */
int struct_version;
/** MQTT 消息有效负载的长度(以字节为单位)。 */
int payloadlen;
/** 指向 MQTT 消息有效负载的指针。 */
void* payload;
/**
* 分配给消息的服务质量 (QoS)。
* QoS 分为三个级别:
* QoS0 “发射后不管” - 消息可能不会被投递
* QoS1 “至少一次” - 消息将被投递,但在某些情况下可能会被投递多次。
* QoS2 “一次且仅一次” - 消息只会被投递一次.
*/
int qos;
/**
* Retained 标志有两个用途,具体取决于与其关联的消息是正在发布还是正在接收。
*
* <b>retained = true</b><br>
* 对于正在发布的消息,设置为 true 表示 MQTT 服务器应保留该消息的副本。然后,该消息将传输给与该消息主题匹配的新订阅者。
* 对于注册新订阅的订阅者,该标志为 true 表示收到的消息不是新消息,而是已被 MQTT 服务器保留的消息。
*
* <b>retained = false</b> <br>
* 对于发布者,这表示该消息不应被 MQTT 服务器保留。
* 对于订阅者,设置为 false 表示这是一条普通消息,由于已发布到服务器而收到。
*/
int retained;
/**
* dup 标志指示此消息是否重复。
* 该标志仅在接收 QoS1 消息时才有意义。当该标志为 true 时,
* 客户端应用程序应采取适当的措施来处理重复消息。这仅是一个输出参数。
*/
int dup;
/** 消息标识符保留供
* MQTT 客户端和服务器内部使用。它只是一个输出参数 - 写入
* 它将毫无意义。它包含传入发布消息的 MQTT 消息 ID。
*/
int msgid;
/**
* 与消息相关的 MQTT V5 属性。
*/
MQTTProperties properties;
} MQTTAsync_message;
#define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer }
/**这是一个回调函数。客户端应用程序必须提供此函数的实现才能启用异步消息接收。
* 该函数通过将其作为参数传递给 MQTTAsync_setCallbacks() 来注册到客户端库。
* 当从服务器收到与客户端订阅匹配的新消息时,客户端库会调用此函数。
* 此函数在与客户端应用程序正在运行的线程不同的线程上执行。
*
* 注意:不应在此回调中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向最初传递给 MQTTAsync_setCallbacks() 的 context 值的指针,该值包含任何特定于应用程序的上下文。
* @param topicName 与接收消息关联的主题。
* @param topicLen 如果 topicName 中嵌入了一个或多个 NULL 字符,则为主题的长度;否则为 topicLen。
* 如果 topicLen 为 0,则 strlen(topicName) 返回的值是可信的。
* 如果 topicLen 大于 0,则可以通过访问长度为 topicLen 的字节数组来检索完整的主题名称。
* @param message 接收消息的 MQTTAsync_message 结构。
* 此结构包含消息有效负载和属性。
* @return 此函数必须返回 0 或 1,以指示消息是否已被客户端应用程序安全接收。
* 返回 1 表示消息已成功处理。
* 要释放消息存储空间,必须调用 ::MQTTAsync_freeMessage。
* 要释放主题名称存储空间,必须调用 ::MQTTAsync_free。
* 返回 0 表示出现问题。在这种情况下,
* 客户端库将重新调用 MQTTAsync_messageArrived() 来尝试再次将消息传递给应用程序。
* 返回 0 时请勿释放消息和主题存储空间,否则重新传递将失败。
*/
typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message);
/** 这是一个回调函数。客户端应用程序必须提供此函数的实现,才能启用异步消息传递到服务器的通知。
* 该函数通过将它作为参数传递给 MQTTAsync_setCallbacks() 来注册到客户端库。
* 客户端应用程序向服务器发布消息后,客户端库会调用此函数。
* 它指示已完成所需握手和确认(针对所请求的服务质量,请参阅
* MQTTAsync_message.qos)。此函数在与客户端应用程序运行的线程不同的线程上执行。
*
* 注意:不应在此回调中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向最初传递给 MQTTAsync_setCallbacks() 的 context 值的指针,该值包含任何特定于应用程序的上下文。
* @param token 与已发布消息关联的 ::MQTTAsync_token。应用程序可以通过将调用
* MQTTAsync_send() 和 MQTTAsync_sendMessage() 返回的令牌与传递给此回调的令牌进行匹配,来检查所有消息是否已正确发布。
*/
typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token);
/**
* 这是一个回调函数。客户端应用程序必须提供此函数的实现,以启用异步通知与服务器的连接断开。
* 此函数通过将函数作为参数传递给MQTTAsync_setCallbacks() 来注册到客户端库。
* 如果客户端断开与服务器的连接,客户端库会调用此函数。客户端应用程序必须采取适当的措施,
* 例如尝试重新连接或报告问题。
* 此函数在与客户端应用程序运行的线程不同的线程上执行。
*
* 注意: 不应在此回调中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向最初传递给 MQTTAsync_setCallbacks() 的 context 值的指针,该值包含任何特定于应用程序的上下文。
* @param cause 断开连接的原因。目前,cause 始终设置为 NULL。
*/
typedef void MQTTAsync_connectionLost(void* context, char* cause);
/**
* 这是一个回调函数,当客户端库成功连接时将被调用。* 如果连接是响应 MQTTAsync_connect 调用而建立的,则无需调用此函数,
* 因为 onSuccess 回调函数已启用。此函数旨在用于启用自动重新连接时,以便当后台重新连接尝试成功时,应用程序将收到通知并可以执行任何必要的操作。
*
* 注意: 不应在此回调中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向最初传递给 MQTTAsync_setCallbacks() 的 context 值的指针,该值包含任何特定于应用程序的上下文。
* @param cause 断开连接的原因。目前,cause 始终设置为 NULL。
*/
typedef void MQTTAsync_connected(void* context, char* cause);
/**
* 这是一个回调函数,当客户端库接收到来自服务器的断开连接数据包时,该函数将被调用。这仅适用于 MQTT V5 及更高版本。
*
* 注意: MQTTAsync_create() 和 MQTTAsync_destroy() 都不应在此回调中调用。
* @param context 指向最初传递给 MQTTAsync_setCallbacks() 的 context 值的指针,该值包含任何特定于应用程序的上下文。
* @param properties 断开连接数据包中的属性。
* @param reasonCode 断开连接数据包的原因代码。
*/
typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties, enum MQTTReasonCodes reasonCode);
/**
* 为客户端设置 MQTTAsync_disconnected() 回调函数。
* @param handle 成功调用 MQTTAsync_create() 后返回的有效客户端句柄。
*
* 注意:不应在此回调函数中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向任何特定于应用程序的上下文的指针。context 指针将传递给每个回调函数,
* 以提供对回调函数中上下文信息的访问。
* @param co 指向 MQTTAsync_connected() 回调函数的指针。NULL 表示删除回调设置。
* @return ::MQTTASYNC_SUCCESS(如果回调设置正确);::MQTTASYNC_FAILURE(如果发生错误)。
*/
LIBMQTT_API int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co);
/** 自动重新连接之前可以更新的连接选项。 */
typedef struct
{
/** 这个结构的亮点是 MQCD。 */
char struct_id[4];
/** 此结构的版本号。将为 0 */
int struct_version;
/**支持 MQTT v3.1 协议的 MQTT 服务器提供身份验证和通过用户名和密码授权的功能。这是用户名参数。
* 将 data 设置为 NULL 即可删除。如需更改,请使用 ::MQTTAsync_allocate 分配新的
* 存储空间 - 该存储空间稍后将由库释放。
*/
const char* username;
/**MQTT 身份验证的密码参数。将 data 设置为 NULL 即可删除。
* 如需更改,请使用 ::MQTTAsync_allocate 分配新的存储空间 - 该存储空间稍后将由库释放。
*/
struct {
int len; /**< binary password length */
const void* data; /**< binary password data */
} binarypwd;
} MQTTAsync_connectData;
#define MQTTAsync_connectData_initializer {{'M', 'Q', 'C', 'D'}, 0, NULL, {0, NULL}}
/**这是一个回调函数,允许客户端应用程序更新连接数据。
* @param data 可由应用程序修改的连接数据。
* @return 返回非零值以更新连接数据,返回零则保持数据不变。
*/
typedef int MQTTAsync_updateConnectOptions(void* context, MQTTAsync_connectData* data);
/**
* 为客户端设置 MQTTAsync_updateConnectOptions() 回调函数。
* @param handle 成功调用 MQTTAsync_create() 后的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。context指针将传递给每个回调函数,以
* 提供对回调中上下文信息的访问。
* @param co 指向 MQTTAsync_updateConnectOptions() 回调函数的指针。NULL 表示删除回调设置。
*/
LIBMQTT_API int MQTTAsync_setUpdateConnectOptions(MQTTAsync handle, void* context, MQTTAsync_updateConnectOptions* co);
/**为客户端设置 MQTTPersistence_beforeWrite() 回调函数。
* @param handle 成功调用 MQTTAsync_create() 后的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。context 指针将传递给回调函数,以便在回调中访问上下文信息。
* @param co 指向 MQTTPersistence_beforeWrite() 回调函数的指针。NULL 表示删除回调设置。
*/
LIBMQTT_API int MQTTAsync_setBeforePersistenceWrite(MQTTAsync handle, void* context, MQTTPersistence_beforeWrite* co);
/**为客户端设置 MQTTPersistence_afterRead() 回调函数。
* @param handle 成功调用 MQTTAsync_create() 后的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。context 指针将传递给回调函数,以便在回调中访问上下文信息。
* @param co 指向 MQTTPersistence_beforeWrite() 回调函数的指针。NULL 表示删除回调设置。
*/
LIBMQTT_API int MQTTAsync_setAfterPersistenceRead(MQTTAsync handle, void* context, MQTTPersistence_afterRead* co);
/** 在响应回调 onFailure 中,API 调用失败后返回的数据。 */
typedef struct{
/** 标识失败请求的令牌. */
MQTTAsync_token token;
/** 标识错误的数字代码. */
int code;
/** 可选文本,用于解释错误。可以为 NULL. */
const char *message;
} MQTTAsync_failureData;
/** 在响应回调 onFailure 中,API 调用失败后返回的数据。*/
typedef struct
{
/** 此结构最引人注目之处。将是 MQFD。 */
char struct_id[4];
/** 此结构的版本号。将为 0 */
int struct_version;
/** 标识失败请求的令牌。*/
MQTTAsync_token token;
/** 返回的 MQTT 原因代码。 */
enum MQTTReasonCodes reasonCode;
/** 确认上的 MQTT 属性(如果有)。 */
MQTTProperties properties;
/** 标识 MQTT 客户端库错误的数字代码。 */
int code;
/** 可选的进一步解释错误的文本。可以为 NULL。 */
const char *message;
/** 发生故障的数据包类型 - 用于发布 QoS 1/2 交换 */
int packet_type;
} MQTTAsync_failureData5;
#define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL, 0}
/** 在响应回调 onSuccess 中,成功完成 API 调用后返回的数据。*/
typedef struct
{
/** 标识成功请求的令牌。可用于稍后引用该请求。*/
MQTTAsync_token token;
/** subscribe、unsubscribe 和 publish 操作可返回的不同值的联合体。*/
union
{
/** 对于 subscribe,服务器返回的订阅的授权 QoS。
* 如果只请求了一个订阅,则对于 subscribeMany 操作也是如此。*/
int qos;
/** 对于 subscribeMany,如果请求了多个订阅,服务器返回的订阅的授权 QoS 列表。*/
int* qosList;
/** 对于 publish,发送至服务器的消息。*/
struct
{
MQTTAsync_message message; /**< 发送至服务器的消息 */
char* destinationName; /**< 消息的主题目标 */
} pub;
/* 对于 connect,连接到的服务器、使用的 MQTT 版本以及 sessionPresent 标志 */
struct
{
char* serverURI; /**< 服务器的连接字符串 */
int MQTTVersion; /**< 正在使用的 MQTT 版本 */
int sessionPresent; /**< 从服务器返回的会话存在标志 */
} connect;
} alt;
} MQTTAsync_successData;
/** 在响应回调 onSuccess 中,成功完成 API 调用后返回的数据。*/
typedef struct
{
char struct_id[4]; /**< 此结构的醒目部分。将为 MQSD。*/
int struct_version; /**< 此结构的版本号。将为 0 */
/** 标识成功请求的令牌。可用于稍后引用该请求。*/
MQTTAsync_token token;
enum MQTTReasonCodes reasonCode; /**< 返回的 MQTT V5 原因代码 */
MQTTProperties properties; /**< 返回的 MQTT V5 属性(如果有)*/
/** 可以为订阅、取消订阅和发布返回的不同值的联合。*/
union
{
/** 对于 subscribeMany,为服务器返回的 reasonCodes 列表。*/
struct
{
int reasonCodeCount; /**< reasonCodes 数组中的原因代码数量 */
enum MQTTReasonCodes* reasonCodes; /**< 一个 reasonCodes 数组 */
} sub;
/** 对于发布,为发送到服务器的消息。 */
struct
{
MQTTAsync_message message; /**< 正在发送到服务器的消息 */
char* destinationName; /**< 消息的主题目标 */
} pub;
/* 对于 connect,返回连接到的服务器、使用的 MQTT 版本以及 sessionPresent 标志 */
struct
{
char* serverURI; /**< 服务器的连接字符串 */
int MQTTVersion; /**< 正在使用的 MQTT 版本 */
int sessionPresent; /**< 服务器返回的 session present 标志 */
} connect;
/** 对于 unsubscribeMany,返回服务器返回的 reasonCodes 列表。 */
struct
{
int reasonCodeCount; /**< reasonCodes 数组中的原因代码数量 */
enum MQTTReasonCodes* reasonCodes; /**< reasonCodes 数组 */
} unsub;
} alt;
} MQTTAsync_successData5;
#define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, {.sub={0,0}}}
/**
* 这是一个回调函数。客户端应用
* 必须提供此函数的实现,才能启用异步
* API 调用成功完成的通知。此函数
* 通过将参数传递给
* ::MQTTAsync_responseOptions 来注册到客户端库。
*
* <b>注意:</b> 不应在此回调中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向最初传递给
* ::MQTTAsync_responseOptions 的 <i>context</i> 值的指针,其中包含任何特定于应用的上下文。
* @param respond 与 API 完成相关的任何成功数据。
*/
typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response);
/**
* 这是一个回调函数,是 MQTT V5 版本的 ::MQTTAsync_onSuccess。
* 客户端应用程序
* 必须提供此函数的实现,才能启用异步
* API 调用成功完成的通知。此函数
* 通过将它作为参数传递给
* ::MQTTAsync_responseOptions 来注册到客户端库。
*
* <b>注意:</b> 不应在此回调中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向最初传递给
* ::MQTTAsync_responseOptions 的 <i>context</i> 值的指针,其中包含任何特定于应用程序的上下文。
* @param respond 任何与 API 完成相关的成功数据。
*/
typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response);
/**
* 这是一个回调函数。客户端应用
* 必须提供此函数的实现,才能启用异步
* API 调用失败通知。此函数
* 通过将参数传递给
* ::MQTTAsync_responseOptions 来注册到客户端库。
*
* <b>注意:</b> 不应在此回调中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向最初传递给
* ::MQTTAsync_responseOptions 的 <i>context</i> 值的指针,该值包含任何特定于应用的上下文。
* @param respond 与 API 完成相关的失败数据。
*/
typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response);
/**
* 这是一个回调函数,是 MQTT V5 版本的 ::MQTTAsync_onFailure。
* 应用程序必须提供此函数的实现,才能启用异步
* API 调用失败通知。此函数
* 通过将它作为参数传递给
* ::MQTTAsync_responseOptions 来注册到客户端库。
*
* <b>注意:</b> 不应在此回调中调用 MQTTAsync_create() 和 MQTTAsync_destroy()。
* @param context 指向最初传递给
* ::MQTTAsync_responseOptions 的 <i>context</i> 值的指针,该值包含任何特定于应用程序的上下文。
* @param respond 与 API 完成相关的失败数据。
*/
typedef void MQTTAsync_onFailure5(void* context, MQTTAsync_failureData5* response);
/** 用于定义调用选项的结构。对于 MQTT 5.0,除了描述响应方法的数据外,还包含输入数据。
* 因此,现在还有一个同义词 ::MQTTAsync_callOptions,以更好地反映其用途。保留此“responseOptions”名称是为了向后兼容。
*
typedef struct MQTTAsync_responseOptions
{
/** 此结构的醒目部分。必须是 MQTR */
char struct_id[4];
/** 此结构的版本号。必须为 0 或 1
* 如果为 0,则表示无 MQTTV5 选项 */
int struct_version;
/**
* 指向回调函数的指针,当 API 调用成功完成时,该函数将被调用。
* 可以设置为 NULL,在这种情况下,将不会收到任何成功完成的指示。
*/
MQTTAsync_onSuccess* onSuccess;
/**
* 指向 API 调用失败时要调用的回调函数的指针。
* 可以设置为 NULL,在这种情况下,不会收到任何失败的指示。
* 完成。
*/
MQTTAsync_onFailure* onFailure;
/**
* 指向任何特定于应用程序的上下文的指针。
* <i>context</i> 指针将传递给成功或失败回调函数,以
* 提供对回调中上下文信息的访问。
*/
void* context;
/**
* 调用会返回一个令牌。它可用于跟踪
* 此请求的状态,无论是在回调中还是在将来的调用中
* 例如 ::MQTTAsync_waitForCompletion。这仅作为输出 - 应用程序的任何
* 更改都将被忽略。
*/
MQTTAsync_token token;
/**
* 指向回调函数的指针,当 API 调用成功完成时,该函数将被调用。
* 可以设置为 NULL,在这种情况下,将不会收到任何成功完成的指示。
*/
MQTTAsync_onSuccess5* onSuccess5;
/**
* 指向回调函数的指针,当 API 调用成功完成时,该函数将被调用。
* 可以设置为 NULL,在这种情况下,将不会收到任何成功完成的指示。
*/
MQTTAsync_onFailure5* onFailure5;
/** MQTT V5 输入属性*/
MQTTProperties properties;
/** MQTT V5 订阅选项,仅与订阅一起使用时。*/
MQTTSubscribe_options subscribeOptions;
/** MQTT V5 订阅选项计数,仅与 subscribeMany 一起使用时。
* subscribe_options_list 数组中的条目数。
*/
int subscribeOptionsCount;
/** MQTT V5 订阅选项数组,仅与 subscribeMany 一起使用时。
*/
MQTTSubscribe_options* subscribeOptionsList;
} MQTTAsync_responseOptions;
#define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL}
/** 自 MQTT 5.0 以来,responseOptions 的同义词,以更好地反映其用法 */
typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions;
#define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer
/**
* 此函数为特定客户端设置全局回调函数。
* 如果您的客户端应用程序未使用特定回调函数,请将
* 相关参数设置为 NULL(消息到达参数除外,该参数必须指定)。
* 任何必要的消息确认和状态通信都将在后台处理,
* 无需客户端应用程序干预。
*
* <b>注意:</b> 调用此函数时,MQTT 客户端必须断开连接。
* @param handle 成功调用 MQTTAsync_create() 后的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。
* <i>context</i> 指针将传递给每个回调函数,以
* 提供对回调中上下文信息的访问。
* @param cl 指向 MQTTAsync_connectionLost() 回调函数的指针。
* 如果您的应用程序不处理连接断开,可以将其设置为 NULL。
* * @param ma 指向 MQTTAsync_messageArrived() 回调函数的指针。
* 如果未设置此回调,则会返回错误。
* 您必须设置此回调,否则将无法传递任何传入消息。
* @param dc 指向 MQTTAsync_deliveryComplete() 回调函数的指针。
* 如果您不想检查是否成功传递,可以将其设置为 NULL。
* @return ::MQTTASYNC_SUCCESS(如果回调设置正确)
* ::MQTTASYNC_FAILURE(如果发生错误)。
*/
LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc);
/**
* 此函数为特定客户端设置连接丢失事件的回调函数。任何必要的消息确认和状态通信均在后台处理,无需客户端应用程序干预。
*
* <b>注意:</b> 调用此函数时,MQTT 客户端必须断开连接。
* @param handle 成功调用 MQTTAsync_create() 后返回的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。
* <i>context</i> 指针将传递给回调函数,以便在回调中访问上下文信息。
* @param cl 指向 MQTTAsync_connectionLost() 回调函数的指针。
* 如果您的应用程序不处理连接断开,可以将其设置为 NULL。
* @return ::MQTTASYNC_SUCCESS(如果回调设置正确);
* ::MQTTASYNC_FAILURE(如果发生错误)。
*/
LIBMQTT_API int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context,
MQTTAsync_connectionLost* cl);
/**
* 此函数为特定客户端设置消息到达事件的回调函数。任何必要的消息确认和状态通信均在后台处理,无需客户端应用程序干预。如果您未设置 messageArrived 回调函数,则不会收到任何订阅消息的通知。
*
* <b>注意:</b> 调用此函数时,MQTT 客户端必须断开连接。
* @param handle 成功调用 MQTTAsync_create() 后返回的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。<i>context</i> 指针将传递给回调函数,以便访问回调中的上下文信息。
* @param ma 指向 MQTTAsync_messageArrived() 回调函数的指针。
* 如果您的应用程序不处理消息接收,可以将其设置为 NULL。
* * @return ::MQTTASYNC_SUCCESS(如果回调设置正确);
* ::MQTTASYNC_FAILURE(如果发生错误)。
*/
LIBMQTT_API int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context, MQTTAsync_messageArrived* ma);
/**
* 此函数为特定客户端设置投递完成事件的回调函数。
* 任何必要的消息确认和状态
* 通信均在后台处理,无需客户端应用程序干预。
*
* <b>注意:</b> 调用此函数时,MQTT 客户端必须断开连接。
*
* @param handle 成功调用 MQTTAsync_create() 后返回的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。 <i>context</i> 指针将传递给回调函数,以便
* 访问回调中的上下文信息。
* @param dc 指向 MQTTAsync_deliveryComplete() 回调函数的指针。
* 如果您不想检查是否成功交付,可以将其设置为 NULL。
* @return ::MQTTASYNC_SUCCESS(如果回调设置正确)
* ::MQTTASYNC_FAILURE(如果发生错误)。
*/
LIBMQTT_API int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context, MQTTAsync_deliveryComplete* dc);
/**
* 为客户端设置 MQTTAsync_connected() 回调函数。
* @param handle 成功调用 MQTTAsync_create() 后返回的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。
* <i>context</i> 指针将传递给每个回调函数,以便
* 在回调中提供对上下文信息的访问。
* @param co 指向 MQTTAsync_connected() 回调函数的指针。NULL 表示删除回调设置。
* @return ::MQTTASYNC_SUCCESS(如果回调设置正确);
* ::MQTTASYNC_FAILURE(如果发生错误)。
*/
LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co);
/**
* 使用之前使用的连接选项重新连接客户端。连接
* 必须先前调用过才能正常工作。
* @param handle 成功调用
* MQTTAsync_create() 后的有效客户端句柄。
* @return ::MQTTASYNC_SUCCESS(如果回调设置正确)
* ::MQTTASYNC_FAILURE(如果发生错误)。
*/
LIBMQTT_API int MQTTAsync_reconnect(MQTTAsync handle);
/** 需要名称/值对的实用程序结构 */
typedef struct
{
const char* name; /**< name string */
const char* value; /**< value string */
} MQTTAsync_nameValue;
/**
* MQTTAsync_connectOptions 定义了几个设置,用于控制客户端连接到 MQTT 服务器的方式。
*
* 以下初始化器中设置了合适的默认值:
* - MQTTAsync_connectOptions_initializer:适用于 MQTT 3.1.1 非 WebSocket 协议
* - MQTTAsync_connectOptions_initializer5:适用于 MQTT 5.0 非 WebSocket 协议
* - MQTTAsync_connectOptions_initializer_ws:适用于 MQTT 3.1.1 WebSocket 协议
* - MQTTAsync_connectOptions_initializer5_ws:适用于 MQTT 5.0 WebSocket 协议
*/
typedef struct
{
/** 这个结构的显著特征,必须是MQTC */
char struct_id[4];
/** 此结构的版本号。必须为 0,1,2,3,4,5,6,7,8.
* 0 表示没有 SSL options 并且没有 serverURIs
* 1 表示没有 serverURIs
* 2 表示没有 MQTTVersion
* 3 表示没有 automatic reconnect options(自动重连选项)
* 4 表示没有 binary password option (just string)
* 5 表示没有 MQTTV5 properties
* 6 表示没有 HTTP headers option
* 7 表示没有 HTTP proxy and HTTPS proxy options
*/
int struct_version;
/** “保持连接”间隔(以秒为单位)定义了客户端和服务器之间应保持无通信的最长时间。
* 客户端将确保在每个保持连接周期内至少有一条消息在网络中传输。
* 如果在该周期内没有数据相关的消息,客户端将发送一个非常小的 MQTT“ping”消息,
* 服务器将确认该消息。保持连接间隔使客户端能够检测到服务器何时不再可用,
* 而无需等待漫长的 TCP/IP 超时。如果您不想进行任何保持连接处理,请设置为 0。
*/
int keepAliveInterval;
/**
* 这是一个布尔值。cleansession 设置控制客户端和服务器在连接和断开连接时的行为。
* 客户端和服务器都维护会话状态信息。此信息用于确保消息的“至少一次”和“恰好一次”传递,
* 以及“恰好一次”接收。会话状态还包含 MQTT 客户端创建的订阅。您可以选择在会话之间维护或丢弃状态信息。
*
* 当 cleansession 为 true 时,状态信息会在连接和断开连接时被丢弃。将 cleansession 设置为 false 可保留状态信息。
* 当您使用 MQTT 客户端应用程序连接时,客户端会使用客户端标识符和服务器地址来识别连接。
* 服务器会检查此客户端的会话信息是否已从先前与服务器的连接中保存。如果先前的会话仍然存在,并且 cleansession=true,
* 则客户端和服务器上的先前会话信息将被清除。如果 cleansession=false,
* 则恢复之前的会话。如果之前的会话不存在,则启动一个新的会话。
*/
int cleansession;
/**
* 这控制着可以同时传输的消息数量。
*/
int maxInflight;
/**
* 这是一个指向 MQTTAsync_willOptions 结构的指针。如果您的
* 应用程序不使用“遗嘱”功能,请将此指针设置为 NULL。
*/
MQTTAsync_willOptions* will;
/**
* 支持 MQTT v3.1 协议的 MQTT 服务器提供身份验证
* 和通过用户名和密码授权的功能。这是用户名参数。
*/
const char* username;
/**
* 支持 MQTT v3.1 协议的 MQTT 服务器提供身份验证
* 和通过用户名和密码授权的功能。这是密码参数。
*/
const char* password;
/**
* 允许连接完成的时间间隔(以秒为单位)。
*/
int connectTimeout;
/**
* TCP 会话期间,未确认的发布请求将在此时间间隔(以秒为单位)后重试。
* 对于 MQTT 3.1.1 及更高版本,除重新连接外,无需重试。
* 0 会关闭会话内重试,并且是推荐的设置。在已经过载的网络中增加重试只会加剧问题。
*/
int retryInterval;
/**
* 这是一个指向 MQTTAsync_SSLOptions 结构的指针。如果您的应用程序不使用 SSL,请将此指针设置为 NULL。
*/
MQTTAsync_SSLOptions* ssl;
/**
* 指向连接成功完成时要调用的回调函数的指针。
* 可以设置为 NULL,在这种情况下将不会收到任何成功完成的指示。
*/
MQTTAsync_onSuccess* onSuccess;
/**
* 指向连接失败时要调用的回调函数的指针。
* 可以设置为 NULL,在这种情况下,不会收到任何失败的指示。
*/
MQTTAsync_onFailure* onFailure;
/**
* 指向任何特定于应用程序的上下文的指针。
* <i>context</i> 指针将传递给成功或失败回调函数,以
* 提供对回调中上下文信息的访问。
*/
void* context;
/**
* serverURIs 数组中的条目数。
*/
int serverURIcount;
/**
* 一个以空字符结尾的字符串数组,用于指定客户端将连接到的服务器。
* 每个字符串的格式为 <i>protocol://host:port</i>。
* <i>protocol</i> 必须是 <i>tcp</i>、<i>ssl</i>、<i>ws</i> 或 <i>wss</i>。
* 启用 TLS 的前缀 (ssl、wss) 仅在链接了 TLS 版本的库时有效。
* 对于 <i>host</i>,您可以指定 IP 地址或域名。例如,要连接到
* 在本地计算机上使用默认 MQTT 端口运行的服务器,请指定 <i>tcp://localhost:1883</i>。
*/
char* const* serverURIs;
/**
* 设置连接时使用的 MQTT 版本。
* MQTTVERSION_DEFAULT (0) = 默认:从 3.1.1 开始,如果失败,则回退到 3.1
* MQTTVERSION_3_1 (3) = 仅尝试 3.1 版本
* MQTTVERSION_3_1_1 (4) = 仅尝试 3.1.1 版本
*/
int MQTTVersion;
/**
* 连接丢失时自动重新连接。0=false,1=true
*/
int automaticReconnect;
/**
* 自动重新连接的最小重试间隔(以秒为单位)。每次重试失败时,间隔加倍。
*/
int minRetryInterval;
/**
* 自动重新连接的最大重试间隔(以秒为单位)。重试失败后,加倍将在此停止。
*/
int maxRetryInterval;
/**
* 可选二进制密码。仅当密码选项为 NULL 时才检查并使用。
*/
struct {
int len; /**< binary password length */
const void* data; /**< binary password data */
} binarypwd;
/*
* MQTT V5 清理启动标志。仅在会话开始时清除状态。
*/
int cleanstart;
/**
* MQTT V5 连接属性
*/
MQTTProperties *connectProperties;
/**
* MQTT V5 中连接中遗嘱消息的属性
*/
MQTTProperties *willProperties;
/**
* 指向连接成功完成时要调用的回调函数的指针。
* 可以设置为 NULL,在这种情况下将不会收到任何成功完成的指示。
*/
MQTTAsync_onSuccess5* onSuccess5;
/**
* 指向连接失败时要调用的回调函数的指针。
* 可以设置为 NULL,在这种情况下,不会收到任何失败的指示。
*/
MQTTAsync_onFailure5* onFailure5;
/**
* WebSocket 的 HTTP 标头
*/
const MQTTAsync_nameValue* httpHeaders;
/**
* HTTP 代理的字符串值。示例:
* - http://your.proxy.server:8080/
* - http://user:pass@my.proxy.server:8080/
*/
const char* httpProxy;
/**
* HTTPS 代理设置。请参阅 ::MQTTAsync_connectOptions.httpProxy 和 @ref HTTP_proxies 部分。
*/
const char* httpsProxy;
} MQTTAsync_connectOptions;
/** MQTT 3.1.1 非 WebSocket 连接的连接选项初始化程序 */
#define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 8, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\
NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
/** MQTT 5.0 非 WebSocket 连接的连接选项初始化程序 */
#define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 8, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\
NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
/** MQTT 3.1.1 WebSockets 连接选项的初始化程序。
* 保持连接间隔设置为 45 秒,以避免 Web 服务器 60 秒不活动超时。
*/
#define MQTTAsync_connectOptions_initializer_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 1, 65535, NULL, NULL, NULL, 30, 0,\
NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
/** MQTT 5.0 WebSockets 连接选项的初始化程序。
* 保持连接间隔设置为 45 秒,以避免 Web 服务器 60 秒不活动超时。
*/
#define MQTTAsync_connectOptions_initializer5_ws { {'M', 'Q', 'T', 'C'}, 8, 45, 0, 65535, NULL, NULL, NULL, 30, 0,\
NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
/**MQTTAsync_willOptions 定义了客户端的 MQTT“遗嘱”(LWT) 设置。
* 如果客户端意外断开与服务器的连接,
* 服务器将代表客户端将 LWT 消息发布到 LWT 主题。
* 这样,其他客户端(订阅了 LWT 主题)
* 就可以知道该客户端已断开连接。要为特定客户端启用 LWT
* 功能,需要在 MQTTAsync_connectOptions 结构体中传递一个指向 MQTTAsync_willOptions 结构体的有效指针,
* 该结构体用于将客户端连接到服务器的
* MQTTAsync_connect() 调用。如果 LWT 函数不是必需的,则可以将指向 MQTTAsync_willOptions 结构的指针设置为 NULL。
*/
typedef struct
{
/** 此结构的 eyecatcher 必须是 MQTW. */
char struct_id[4];
/** 此结构的版本号。必须为 0 或 1, 0 表示没有二进制文件将支持消息. */
int struct_version;
/** 将发布 LWT 消息的 LWT 主题. */
const char* topicName;
/** LWT payload. */
const char* message;
/** LWT 消息的保留标志(参见 MQTTAsync_message.retained). */
int retained;
/** LWT 消息的服务质量设置(参见 MQTTAsync_message.qos 和 @ref qos). */
int qos;
/** 二进制形式的 LWT 有效负载。仅当消息选项为 NULL 时才检查和使用此项. */
struct
{
int len; /**< binary payload length */
const void* data; /**< binary payload data */
} payload;
} MQTTAsync_willOptions;
#define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } }
#define MQTT_SSL_VERSION_DEFAULT 0
#define MQTT_SSL_VERSION_TLS_1_0 1
#define MQTT_SSL_VERSION_TLS_1_1 2
#define MQTT_SSL_VERSION_TLS_1_2 3
/**
* 此函数创建一个 MQTT 客户端,准备连接到指定的服务器并使用指定的持久存储(请参阅MQTTAsync_persistence)。
* 另请参阅 MQTTAsync_destroy()。
* @param handle ::MQTTAsync 句柄的指针。此函数成功返回后,句柄将填充有效的客户端引用。
* @param serverURI 以空字符结尾的字符串,指定客户端将连接到的服务器。其格式为:
* <i>protocol://host:port</i> where <i>protocol</i> must be:
* <br>
* @em tcp:// or @em mqtt:// - Insecure TCP
* <br>
* @em ssl:// or @em mqtts:// - Encrypted SSL/TLS
* <br>
* @em ws:// - Insecure websockets
* <br>
* @em wss:// - Secure web sockets
* <br>
* 仅当链接了 TLS 版本的库时,启用 TLS 的前缀 (ssl、mqtts、wss) 才有效。
*
* 对于 <i>host</i>,您可以指定 IP 地址或主机名。例如,要使用
* 默认 MQTT 端口连接到在本地计算机上运行的服务器,请指定 <i>tcp://localhost:1883</i>。
*
* @param clientId 当客户端连接到服务器时传递给服务器的客户端标识符。它是一个以空字符结尾的 UTF-8 编码字符串。
* @param persistence_type 客户端要使用的持久性类型:
* <br>
* ::MQTTCLIENT_PERSISTENCE_NONE:使用内存持久性。如果运行客户端的设备或系统发生故障或关闭,则任何正在传输的消息的当前
* 状态都会丢失,并且即使在 QoS1 和 QoS2 下,某些消息也可能无法传递。
* <br>
* ::MQTTCLIENT_PERSISTENCE_DEFAULT:使用默认(基于文件系统)
* 持久性机制。有关正在传输的消息的状态将保存在持久存储中,并在发生意外故障时提供一些防止消息丢失的保护。
* <br>
* ::MQTTCLIENT_PERSISTENCE_USER:使用特定于应用程序的持久性
* 实现。使用这种类型的持久性可将持久性机制的控制权交给应用程序。应用程序必须实现
* MQTTClient_persistence 接口。
* @param persistence_context 如果应用程序使用::MQTTCLIENT_PERSISTENCE_NONE 持久性,则此参数未使用,应设置为 NULL。
* 对于 ::MQTTCLIENT_PERSISTENCE_DEFAULT 持久性,它
* 应设置为持久性目录的位置(如果设置为
* NULL,则使用的持久性目录是工作目录)。
* 使用 ::MQTTCLIENT_PERSISTENCE_USER 持久性的应用程序将此
* 参数设置为指向有效的 MQTTClient_persistence 结构。
* @return ::MQTTASYNC_SUCCESS 如果客户端创建成功,否则返回错误代码。
*/
LIBMQTT_API int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId, int persistence_type, void* persistence_context);
/** ::MQTTAsync_createWithOptions 调用的选项 */
typedef struct
{
/** 这个结构的亮点一定是 MQCO。 */
char struct_id[4];
/** 此结构的版本号。必须为 0、1、2 或 3
* 0 表示无 MQTTVersion
* 1 表示无 allowDisconnectedSendAtAnyTime、deleteOldestMessages 和 restoreMessages
* 2 表示无 persistQoS0
*/
int struct_version;
/** 是否允许在客户端库未连接时发送消息。 */
int sendWhileDisconnected;
/** 允许缓冲的最大消息数。此参数旨在用于
* 限制客户端未连接时排队的消息数。它也适用于
* 客户端已连接的情况,因此必须大于 0。*/
int maxBufferedMessages;
/** MQTT 版本是 3.1、3.1.1 还是 5。要使用 V5,必须设置此项。
* 此处必须选择 MQTT V5,因为在 create 调用期间会初始化消息持久性,
* 并且我们想知道任何持久化消息的格式是否
* 适合我们要连接的 MQTT 版本。选择 3.1 或
* 3.1.1 并尝试读取 5.0 持久化消息将导致 create 时出错。*/
int MQTTVersion;
/**
* 允许在首次成功连接之前断开连接时发送消息。
*/
int allowDisconnectedSendAtAnyTime;
/** 当达到缓冲消息的最大数量时,删除最旧的消息,而不是最新的消息。
*/
int deleteOldestMessages;
/** 创建时从持久化中恢复消息 - 或者清除它。
*/
int restoreMessages;
/** 保留 QoS0 发布命令 - 可选择不保留它们。
*/
int persistQoS0;
} MQTTAsync_createOptions;
#define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_DEFAULT, 0, 0, 1, 1}
#define MQTTAsync_createOptions_initializer5 { {'M', 'Q', 'C', 'O'}, 2, 0, 100, MQTTVERSION_5, 0, 0, 1, 1}
LIBMQTT_API int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId, int persistence_type,
void* persistence_context, MQTTAsync_createOptions* options);
/**
* MQTTAsync_sslProperties 定义了使用 OpenSSL 库建立 SSL/TLS 连接的设置。
* 它涵盖以下场景:
* - 服务器身份验证:客户端需要服务器的数字证书。该证书包含在
* 包含可信资料的存储库(也称为“信任存储库”)中。
* - 相互身份验证:客户端和服务器在 SSL 握手期间都会进行身份验证。除了信任存储库中的服务器数字证书外,客户端还需要自己的
* 数字证书以及存储在“密钥存储库”中的用于签署其数字证书的私钥。
* - 匿名连接:客户端和服务器均无需身份验证,也无需任何凭据即可建立 SSL 连接。
* 请注意,此场景并非完全安全,因为它容易受到中间人攻击。
*/
typedef struct
{
/** 此结构的醒目部分。必须是 MQTS */
char struct_id[4];
/** 此结构的版本号。必须为 0、1、2、3、4 或 5。
* 0 表示无 sslVersion
* 1 表示无 verify、CApath
* 2 表示无 ssl_error_context、ssl_error_cb
* 3 表示无 ssl_psk_cb、ssl_psk_context 和 disableDefaultTrustStore
* 4 表示无 protos、protos_len
*/
int struct_version;
/** 包含客户端信任的公共数字证书的 PEM 格式的文件。 */
const char* trustStore;
/** PEM 格式的文件,包含客户端的公共证书链。它还可能包含客户端的私钥。*/
const char* keyStore;
/** 如果 sslKeyStore 中未包含此设置,则此设置指向包含客户端私钥的 PEM 格式的文件。客户端私钥。*/
const char* privateKey;
/** 如果加密则加载客户端私钥的密码。 */
const char* privateKeyPassword;
/**
* 客户端在 SSL 握手期间将向服务器提供的密码套件列表。有关密码列表格式的完整说明,请参阅 OpenSSL 在线文档:
* http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
* 如果省略此设置,则其默认值为“ALL”,即所有密码套件(不包括
* 不提供加密的密码套件)都将被考虑。
* 此设置可用于设置 SSL 匿名连接(例如,“aNULL”字符串值)。
*/
const char* enabledCipherSuites;
/** True/False 选项用于启用服务器证书验证 **/
int enableServerCertAuth;
/** 要使用的 SSL/TLS 版本。请指定 MQTT_SSL_VERSION_DEFAULT (0)、
* MQTT_SSL_VERSION_TLS_1_0 (1)、MQTT_SSL_VERSION_TLS_1_1 (2) 或 MQTT_SSL_VERSION_TLS_1_2 (3) 之一。
* 仅当 struct_version >= 1 时使用。
*/
int sslVersion;
/*** 是否执行连接后检查,包括证书是否
* 与给定的主机名匹配。
* 仅当 struct_version >= 2 时才存在
*/
int verify;
/**摘自 OpenSSL 文档:
* 如果 CApath 不为 NULL,则指向包含 PEM 格式 CA 证书的目录。
* 仅当 struct_version >= 2 时才存在
*/
const char* CApath;
/**
* OpenSSL 错误处理程序 ERR_print_errors_cb 的回调函数
* 仅当 struct_version >= 3 时存在
*/
int (*ssl_error_cb) (const char *str, size_t len, void *u);
/**
* OpenSSL 错误处理程序 ERR_print_errors_cb 的特定于应用程序的上下文
* 仅当 struct_version >= 3 时存在
*/
void* ssl_error_context;
/**
* 用于设置 TLS-PSK 选项的回调函数。参数与 SSL_CTX_set_psk_client_callback 的参数相对应,但 u 指向的是 ssl_psk_context 指针。
* 仅当 struct_version >= 4 时才存在
*/
unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u);
/** * ssl_psk_cb 的应用程序特定上下文 * 仅当结构版本 >= 4 时才存在 */
void* ssl_psk_context;
/**
* 不加载默认 SSL CA。应与 PSK 一起使用,以确保
* 已安装证书的常规服务器不被接受。
* 仅当 struct_version >= 4 时才存在
*/
int disableDefaultTrustStore;
/**
* 协议列表必须采用线路格式,该格式定义为一个非空的、带有 8 位长度前缀的字节字符串向量。
* 长度前缀字节不包含在长度中。每个字符串的长度限制为 255 个字节。长度为 0 的字节字符串无效。
* 截断的字节字符串无效。
* 请查看 SSL_CTX_set_alpn_protos 的文档。
* 仅当 struct_version >= 5 时才存在。
*/
const unsigned char *protos;
/**
* protos 向量的长度
* 仅当 struct_version >= 5 时存在
*/
unsigned int protos_len;
} MQTTAsync_SSLOptions;
#define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 5, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0 }
/**
* 为客户端设置 MQTTAsync_connected() 回调函数。
* @param handle 成功调用MQTTAsync_create() 后获得的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。context 指针被传递给每个回调函数,以提供对回调中的上下文信息的访问。
* @param co 指向 MQTTAsync_connected() 回调函数的指针。NULL 将删除回调设置。
* @return ::MQTTASYNC_SUCCESS 如果回调设置正确,::MQTTASYNC_FAILURE 如果发生错误。
* @note: 1.初次连接成功时触发:调用 MQTTAsync_connect(),连接成功(即 broker 返回 CONNACK)后,会在 onSuccess 回调之后 异步 调用 MqttAsyncConnected()
* 2.断线自动重连成功后触发:启用了自动重连(MQTTAsync_connectOptions.automaticReconnect = 1),当客户端从断线状态重新连上 broker 时,会调用 MqttAsyncConnected()
* 3.断开连接时不会触发: 断开连接时会调用 connectionLost() 回调,而不是 connected()。
* 4. 调用 setConnected() 时不会立即触发: 调用 MQTTAsync_setConnected() 只是注册回调,不会立即触发.
*/
LIBMQTT_API int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co);
/**
* 此函数尝试使用指定的选项将先前创建的客户端(请参阅MQTTAsync_create())连接到 MQTT 服务器。如果您
* 想要启用异步消息和状态通知,则必须在 MQTTAsync_connect() 之前调用MQTTAsync_setCallbacks()。
* @param handle 成功调用MQTTAsync_create() 后获得的有效客户端句柄。
* @param options 指向有效 MQTTAsync_connectOptions 结构的指针。
* @return ::MQTTASYNC_SUCCESS 客户端连接请求被接受。
* 如果客户端无法连接到服务器,则会通过 onFailure 回调(如果已设置)返回错误代码。
* MQTT 协议会返回大于 0 的错误代码:
* <b>1</b>: Connection refused: 协议版本不可接受
* <b>2</b>: Connection refused: 标识符被拒绝
* <b>3</b>: Connection refused: 服务器不可用
* <b>4</b>: Connection refused: 用户名或密码错误
* <b>5</b>: Connection refused: 未授权
* <b>6-255</b>: 保留以供将来使用
*/
LIBMQTT_API int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options);
/** ::MQTTAsync_disconnect 调用的选项 */
typedef struct
{
/** 此结构的醒目元素。必须是 MQTD。*/
char struct_id[4];
/** 此结构的版本号。必须为 0 或 1。0 表示没有 V5 属性 */
int struct_version;
/**客户端将断开连接延迟最多此时间(以
* 毫秒为单位),以便完成正在进行的消息传输。
*/
int timeout;
/**指向一个回调函数的指针,当断开连接成功完成时,该函数将被调用。
* 可以设置为 NULL,在这种情况下,将不会收到任何成功完成的指示。
*/
MQTTAsync_onSuccess* onSuccess;
/**指向断开连接失败时要调用的回调函数的指针。
* 可以设置为 NULL,在这种情况下,不会收到任何失败的指示。
* 完成。
*/
MQTTAsync_onFailure* onFailure;
/**指向任何特定于应用程序的上下文的指针。
* <i>context</i> 指针将传递给成功或失败回调函数,以
* 提供对回调中上下文信息的访问。
*/
void* context;
/**MQTT V5 输入属性*/
MQTTProperties properties;
/**MQTTV5 断开连接的原因代码*/
enum MQTTReasonCodes reasonCode;
/**指向一个回调函数的指针,当断开连接成功完成时,该函数将被调用。
* 可以设置为 NULL,在这种情况下,将不会收到任何成功完成的指示。
*/
MQTTAsync_onSuccess5* onSuccess5;
/**
* 指向断开连接失败时要调用的回调函数的指针。
* 可以设置为 NULL,在这种情况下,不会收到任何失败的指示。
*/
MQTTAsync_onFailure5* onFailure5;
} MQTTAsync_disconnectOptions;
#define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL,\
MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL }
#define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\
MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL }
/**
* 此函数为特定客户端设置全局回调函数。如果您的客户端应用程序不使用特定回调,请将相关参数设置为 NULL(消息到达除外,必须提供该参数)。
* 任何必要的消息确认和状态通信均在后台处理,无需客户端应用程序进行任何干预。
*
* Note: 调用此函数时,MQTT 客户端必须断开连接。
* @param handle 成功调用 MQTTAsync_create() 后获得的有效客户端句柄。
* @param context 指向任何特定于应用程序的上下文的指针。context 指针被传递给每个回调函数,以提供对回调中的上下文信息的访问。
* @param cl 指向 MQTTAsync_connectionLost() 回调函数的指针。如果您的应用程序不处理断开连接,您可以将其设置为 NULL。
* @param ma 指向 MQTTAsync_messageArrived() 回调函数的指针。如果未设置此回调,则会返回错误。您必须设置此回调,否则将无法传递任何传入消息。
* @param dc 指向 MQTTAsync_deliveryComplete() 回调函数的指针。如果您不想检查是否成功交付,可以将其设置为 NULL。
* @return ::MQTTASYNC_SUCCESS 如果回调设置正确,
* ::MQTTASYNC_FAILURE 如果发生错误。
*/
LIBMQTT_API int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl, MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc);
/**
* 此函数允许客户端应用程序测试客户端当前是否已连接到 MQTT 服务器。
* @param handle 成功调用 MQTTAsync_create() 后有效的客户端句柄。
* @return Boolean 如果客户端已连接,则返回 true,否则返回 false。
*/
LIBMQTT_API int MQTTAsync_isConnected(MQTTAsync handle);
/**
* 尝试让客户端订阅单个主题,该主题可能包含通配符(请参阅@ref wildcard。
* contain wildcards (see @ref wildcard).
* 此调用还指定了 @ref 为订阅请求的 qos(另请参阅 MQTTAsync_subscribeMany())。
* @param handle 成功调用 MQTTAsync_create() 后获得的有效客户端句柄。
* @param topic 订阅主题,可能包含通配符。
* @param qos 请求的订阅服务质量。
* @param response 指向响应选项结构的指针。用于设置回调函数。
* @return ::MQTTASYNC_SUCCESS 如果订阅请求成功。如果注册订阅时出现问题,则会返回错误代码。
*
*/
LIBMQTT_API int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response);
/**
* 此函数尝试将客户端订阅到一系列主题,这些主题可能
* 包含通配符(请参阅 @ref wildcard)。此调用还指定了
* @ref 为每个主题请求的 QoS(另请参阅 MQTTAsync_subscribe())。
* @param handle 成功调用
* MQTTAsync_create() 后返回的有效客户端句柄。
* @param count 客户端请求订阅的主题数量。
* @param topic 一个长度为 <i>count</i> 的数组,其中包含指向
* 主题的指针,每个主题可能包含通配符。
* @param qos 一个长度为 <i>count</i> 的数组,其中包含 @ref qos
* 值。qos[n] 是为 topic[n] 请求的 QoS。
* @param respond 一个指向响应选项结构的指针。用于设置回调函数。
* @return ::MQTTASYNC_SUCCESS(如果订阅请求成功)。
* 如果注册订阅时出现问题,则会返回错误代码。
*/
LIBMQTT_API int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, const int* qos, MQTTAsync_responseOptions* respond);
/**
* 此函数尝试删除由指定客户端做出的现有订阅。
* @param handle 成功调用 MQTTAsync_create() 后获得的有效客户端句柄。
* @param topic 要删除的订阅的主题,可能包含通配符(请参阅@ref wildcard)。
* @param response 指向响应选项结构的指针。用于设置回调函数。
* @return ::MQTTASYNC_SUCCESS 如果删除订阅。如果删除订阅时出现问题,则会返回错误代码。
*/
LIBMQTT_API int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response);
/**
* 此函数尝试移除指定客户端对一系列主题的现有订阅。
* @param handle 成功调用 MQTTAsync_create() 后返回的有效客户端句柄。
* @param count 待移除的订阅数量。
* @param topic 指向待移除订阅主题的指针数组(长度为 <i>count</i>),每个指针可以包含通配符。
* @param respond 指向响应选项结构的指针,用于设置回调函数。
* @return ::MQTTASYNC_SUCCESS(如果订阅已移除)。
* 如果移除订阅时出现问题,则返回错误代码。
*/
LIBMQTT_API int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* respond);
/**
* 此函数尝试将消息发布到给定主题(另请参阅
* ::MQTTAsync_sendMessage())。如果 QoS 大于 0,则此函数成功返回时会发出 ::MQTTAsync_token。
* 如果客户端应用程序需要
* 测试消息是否成功送达,则应设置回调函数
* (请参阅 ::MQTTAsync_onSuccess() 和 ::MQTTAsync_deliveryComplete())。
* @param handle 成功调用
* MQTTAsync_create() 后的有效客户端句柄。
* @param destinationName 与此消息关联的主题。
* @param payloadlen 有效负载的长度(以字节为单位)。
* @param payload 指向消息有效负载字节数组的指针。
* @param qos 消息的 @ref qos。
* @param retained 消息的 retained 标志。
* @param respond 指向 ::MQTTAsync_responseOptions 结构的指针。用于设置回调函数。
* 此参数为可选参数,可设置为 NULL。
* 如果消息被接受发布,则返回 ::MQTTASYNC_SUCCESS。
* 如果接受消息时出现问题,则返回错误代码。
*/
LIBMQTT_API int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* load, int qos,
int retained, MQTTAsync_responseOptions* respond);
/**
* 此函数尝试将消息发布到给定主题(另请参阅
* MQTTAsync_publish())。当以下情况发生时,会发出 ::MQTTAsync_token:
* 如果 QoS 大于 0,则此函数成功返回。
* 如果客户端应用程序需要
* 测试消息是否成功送达,则应设置回调函数
* (请参阅 ::MQTTAsync_onSuccess() 和 ::MQTTAsync_deliveryComplete())。
* @param handle 成功调用 MQTTAsync_create() 后的有效客户端句柄。
* @param destinationName 与此消息关联的主题。
* @param msg 指向有效 MQTTAsync_message 结构的指针,该结构包含
* 待发布消息的有效负载和属性。
* @param respond 指向 ::MQTTAsync_responseOptions 结构的指针。用于设置回调函数。
* 如果消息被接受发布,则返回 ::MQTTASYNC_SUCCESS。
* 如果接受消息时出现问题,则返回错误代码。
*/
LIBMQTT_API int MQTTAsync_sendMessage(MQTTAsync 句柄, const char* 目标名称, const MQTTAsync_message* 消息, MQTTAsync_responseOptions* 响应);
/**
* 此函数设置一个指向令牌数组的指针,该数组包含当前正在传输(待完成)的消息。
*
* <b>重要提示:</b>用于保存令牌数组的内存在此函数中已通过 malloc() 分配。客户端应用程序负责在不再需要时释放此内存。
* @param handle 成功调用 MQTTAsync_create() 后生成的有效客户端句柄。
* @param tokens 指向 ::MQTTAsync_token 的指针地址。
* 当函数成功返回时,该指针指向一个
* 表示待完成消息的令牌数组。数组的最后一个成员设置为 -1,表示没有其他令牌。如果没有待完成的令牌,则指针设置为 NULL。
* 如果函数成功返回,则返回 ::MQTTASYNC_SUCCESS。
* 如果获取待处理令牌列表时出现问题,则返回错误代码。
*/
LIBMQTT_API int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens);
/**
* 测试与令牌对应的请求是否完成。
*
* @param handle 成功调用 MQTTAsync_create() 后的有效客户端句柄。
* @param token 与请求关联的 ::MQTTAsync_token。
* @return 如果请求已完成,则返回 1;否则返回 0。
*/
#define MQTTASYNC_TRUE 1
LIBMQTT_API int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token);
/**
* 等待与令牌对应的请求完成。这仅适用于
* QoS 大于 0 的消息。QoS 0 消息没有 MQTT 令牌。
* 对于 QoS 0 消息,此函数始终返回 ::MQTTASYNC_SUCCESS。
*
* @param handle 成功调用 MQTTAsync_create() 后的有效客户端句柄。
* @param token 与请求关联的 ::MQTTAsync_token。
* @param timeout 等待完成的最长时间,以毫秒为单位。
* @return ::MQTTASYNC_SUCCESS(如果请求已在分配的时间内完成);
* 否则,返回 ::MQTTASYNC_FAILURE 或 ::MQTTASYNC_DISCONNECTED。
*/
LIBMQTT_API int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout);
/**
* 此函数释放分配给 MQTT 消息的内存,包括
* 分配给消息有效负载的额外内存。客户端应用程序
* 在消息完全处理后调用此函数。<b>重要提示:</b>此函数不会释放分配给消息主题字符串的内存。客户端应用程序需要使用 MQTTAsync_free() 库函数释放此内存。
* @param msg 指向待释放的 ::MQTTAsync_message 结构体的指针地址。
*/
LIBMQTT_API void MQTTAsync_freeMessage(MQTTAsync_message** msg);
/**
* 此函数释放由 MQTT C 客户端库分配的内存,尤其是
* 主题名称。在 Windows 上,当客户端库和应用程序
* 使用不同版本的 C 编译器编译时,需要使用此函数。因此,在释放任何 MQTT C 客户端分配的内存时,始终使用此函数是一个好策略。
@param ptr 指向要释放的客户端库存储的指针。
*/
LIBMQTT_API void MQTTAsync_free(void* ptr);
/**
* 此函数用于分配内存以供 MQTT C 客户端库使用或释放,
* 尤其是 ::MQTTPersistence_afterRead 和 ::MQTTPersistence_beforeWrite
* 回调中的数据。在 Windows 上,当客户端库和应用程序
* 使用不同版本的 C 编译器编译时,需要使用此函数。
* @param size 待分配内存的大小。
*/
LIBMQTT_API void* MQTTAsync_malloc(size_t size);
/**
* 此函数释放分配给 MQTT 客户端的内存(参见
* MQTTAsync_create())。当客户端不再需要时,应调用此函数。
* @param handle 指向要释放的 ::MQTTAsync 结构的句柄的指针。
*/
LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle);
/**
* 此函数设置将在跟踪回调中返回的跟踪信息级别。
* @param level 所需的跟踪级别
*/
LIBMQTT_API void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level);
/**
* 如果您想要接收跟踪信息,则必须实现此回调函数原型。
* 请勿在此回调函数中调用任何其他 Paho API 调用 - 否则可能会导致不可预测的行为。
* @param level 返回消息的跟踪级别。
* @param message 跟踪消息。这是一个指向静态缓冲区的指针,
* 该缓冲区将在每次调用时被覆盖。如果您想保留此数据以备后用,则必须复制此数据。
*/
typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message);
/**
* 此函数根据需要设置跟踪回调。如果设置为 NULL,
* 将不会返回任何跟踪信息。默认跟踪级别为
* MQTTASYNC_TRACE_MINIMUM。
* @param callback 指向处理跟踪信息的函数的指针。
*/
LIBMQTT_API void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback);
/**
* 此函数返回库的版本信息。
* 将不会返回任何跟踪信息。默认跟踪级别为
* MQTTASYNC_TRACE_MINIMUM
* @return 一个描述库的字符串数组。最后一项为 NULL 指针。
*/
LIBMQTT_API MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void);
/**
* 返回指向错误代码字符串表示形式的指针,或 NULL。
* 使用后不释放。如果错误代码未知,则返回 NULL。
* @param code MQTTASYNC_ 返回代码。
* @return 错误代码的静态字符串表示。
*/
LIBMQTT_API const char* MQTTAsync_strerror(int code);
/**
* 此函数尝试断开客户端与 MQTT 服务器的连接。为了允许客户端有时间完成处理调用此函数时正在传输的消息,需要指定超时期限。
* 超时期限到期后,即使仍有未完成的消息确认,客户端也会断开连接。
* 客户端下次连接到同一服务器时,任何未完成的 QoS 1 或 2
* 消息都将根据上一个连接和新连接的 cleansession 设置进行重试(请参阅
* MQTTAsync_connectOptions.cleansession 和 MQTTAsync_connect())。
* @param handle 成功调用 MQTTAsync_create() 后获得的有效客户端句柄。
* @param options 客户端最多会延迟断开连接此时间(以毫秒为单位),以允许正在进行的消息传输完成。
* @return ::MQTTASYNC_SUCCESS(如果客户端成功断开与服务器的连接)。如果客户端无法断开与服务器的连接,则返回错误代码
****/
LIBMQTT_API int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options);
/**
* 此函数释放分配给 MQTT 客户端的内存(请参阅
* MQTTAsync_create())。当客户端不再需要时,应调用此函数。
* @param handle 成功调用 MQTTAsync_create() 后获得的有效客户端句柄。
*/
LIBMQTT_API void MQTTAsync_destroy(MQTTAsync* handle);
/*****************************************************************************************
* @cond MQTTAsync_main
* @page 异步线程
* 客户端应用程序在多个线程上运行。
* 握手和网络连接维护的处理在后台执行。
* 此 API 是线程安全的:函数可以被多个应用程序调用。
* 线程。
* 通过调用在库中注册的回调函数,向客户端提供状态和消息接收通知。
* 应用程序可以通过调用
* MQTTAsync_setCallbacks()(参见 MQTTAsync_messageArrived()、
* MQTTAsync_connectionLost() 和 MQTTAsync_deliveryComplete())。
* 此外,某些函数允许在 ::MQTTAsync_responseOptions 结构中为单个请求设置成功和失败回调。
* 应用程序可以编写为回调函数链。
*
* @page 回调 回调
* 此 API 中的任何函数都可以在回调中使用。但是,不建议在回调中使用 ::MQTTAsync_waitForCompletion,因为它是唯一一个可能需要一些时间才能完成的 API 调用,这可能会导致不可预测的行为。所有其他 API 调用都旨在快速完成,并在后台启动请求,并通过其他回调通知成功或失败。
*
* 如果没有分配回调,则将包含消息到达回调。
* 如果应用程序是纯发布者,并且未订阅任何主题,则可以执行此操作。但是,如果收到了消息,但未设置消息到达回调,则这些消息将累积并占用内存,因为没有空间可以传递它们。
* 系统将写入一条日志消息以突出显示问题,但这取决于应用程序是否能够防止这种情况发生。
*
* @page auto_reconnect 自动重新连接
* 客户端库在连接失败时自动重新连接的功能已在 1.1 版中添加。连接丢失回调
* 允许灵活地响应连接丢失,因此几乎任何
* 行为都可以通过这种方式实现。自动重新连接的优势在于
* 使用起来更简单。
*
* 要启用自动重新连接,请将连接选项字段
* 中的automaticReconnect设置为非零值。下次连接尝试前的最小和最大时间
* 也可以设置,默认值分别为 1 秒和
* 60 秒。每次重新连接失败时,重试间隔都会加倍,直到
* 达到最大值,并一直保持到连接
* 成功重新建立后重置。
*
* 重新连接尝试成功后,将调用 ::MQTTAsync_connected 回调
* 函数(如果通过调用 ::MQTTAsync_setConnected 设置了该函数)。这允许
* 应用程序执行任何必要的操作,例如修改订阅。
*
* @page offline_publish 断开连接时发布
* 此功能最初不可用,因为启用持久性后,
* 消息可能会存储在本地,而无需知道是否可以发送。
* 客户端应用程序可能创建了错误的代理,
* 例如,代理地址或端口。
*
* 要在应用程序断开连接时也能发布消息,
* 必须使用 ::MQTTAsync_createWithOptions 而不是 ::MQTTAsync_create 来
* 创建客户端对象。::MQTTAsync_createOptions 字段的 sendWhileDisconnected
* 必须设置为非零值,并且 maxBufferedMessages 字段必须根据需要设置 -
* 默认值为 100。
*
* 可以调用 ::MQTTAsync_getPendingTokens 来返回等待发送或发送过程尚未完成的消息 ID。
*
* @page wildcard 订阅通配符
* 每条 MQTT 消息都包含一个对其进行分类的主题。MQTT 服务器使用
* 主题来确定哪些订阅者应该接收发布到
* 服务器的消息。
*
* 假设服务器接收来自多个环境传感器的消息。
* 每个传感器都将其测量数据作为一条消息发布,并关联一个
* 主题。订阅应用程序需要知道最初是哪个传感器
* 发布了每条收到的消息。因此,使用唯一的主题来标识
* 每个传感器和测量类型。诸如 SENSOR1TEMP、
* SENSOR1HUMIDITY、SENSOR2TEMP 等主题可以实现这一点,但灵活性不够。
* 如果以后系统中添加了其他传感器,则必须修改订阅应用程序才能接收这些传感器。
*
* 为了提供更大的灵活性,MQTT 支持分层主题命名空间。
* 这使得应用程序设计人员可以组织主题以简化其管理。
* 层次结构中的级别由“/”字符分隔,
* 例如 SENSOR/1/HUMIDITY。发布者和订阅者使用这些
* 分层主题,如上所述。
*
* 对于订阅,支持两个通配符:
* <ul>
* <li>“#”字符表示层次结构的完整子树,
* 因此必须是订阅主题字符串中的最后一个字符,例如
* SENSOR/#。这将匹配任何以 SENSOR/ 开头的主题,例如
* SENSOR/1/TEMP 和 SENSOR/2/HUMIDITY。</li>
* <li>“+”字符表示层次结构的单个级别,用于分隔符之间。例如,SENSOR/+/TEMP 将匹配
* SENSOR/1/TEMP 和 SENSOR/2/TEMP。</li>
* </ul>
* 发布者不得在其主题名称中使用通配符。
* 确定主题层次结构是系统设计中的重要一步。
*
* @page qos 服务质量
* MQTT 协议为在客户端和服务器之间传递消息提供了三种服务质量:
* “最多一次”、“至少一次”和
* “恰好一次”。
*
* 服务质量 (QoS) 是正在发布的单个消息的属性。
* 应用程序通过将 MQTTAsync_message.qos 字段设置为所需值来设置特定消息的 QoS。
*
* 订阅客户端可以设置服务器用于发送与客户端订阅匹配的消息的最大服务质量。
* MQTTAsync_subscribe() 和 MQTTAsync_subscribeMany() 函数设置此
* 最大值。因此,转发给订阅者的消息的 QoS 可能与
* 原始发布者赋予该消息的 QoS 不同。
* 将使用这两个值中较低的一个值来转发消息。
* *
* 这三个级别分别是:
*
* <b>QoS0,最多一次</b>:消息最多传递一次,否则可能根本不传递。消息在网络上的传递不会被确认。消息不会被存储。如果客户端断开连接或服务器发生故障,消息可能会丢失。QoS0 是最快的传输模式。有时也称为“发射后不管”。
*
* MQTT 协议不要求服务器将 QoS0 的发布转发给客户端。如果客户端在服务器接收发布时断开连接,则发布可能会被丢弃,具体取决于服务器的实现。
*
* <b>QoS1,至少一次</b>:消息始终至少传递一次。如果在发送方收到确认之前发生故障,则消息可能会被传递多次。消息必须存储在发送方本地,
* 直到发送方收到接收方已发布的确认。
* 消息将被存储,以防需要再次发送。
*
* <b>QoS2,恰好一次:</b> 消息始终只传递一次。
* 消息必须存储在发送方本地,直到发送方收到接收方已发布的确认。
* 消息将被存储,以防需要再次发送。QoS2 是最安全但速度最慢的传输模式。与 QoS1 相比,QoS2 使用更复杂的握手和确认序列,以确保不会发生消息重复。
* @page publish 发布示例
*****************************************************************************************/