解决miniblink 回调函数 on_wkeDownload2Callback 返回值为kWkeDownloadOptCacheData 程序异常

本文介绍如何在Miniblink中使用POST方式下载文件,详细解释了通过自定义wkeOnDownload2函数及修改源码来实现下载需求的过程。

接上篇,用miniblink 的GET方式下载文件,他的几个Demo 都可以下载文件。但是,如果用post data 方式,然后服务器返回 Content-Disposition 的文件头,而且要下载的数据在 response data里面的话,miniblink 是没有提供接口的。 一般来说,都是用wkeOnDownload 函数,设置好回调函数,在 typedef bool(WKE_CALL_TYPE*wkeDownloadCallback)(wkeWebView webView, void* param, const char* url); 中有 却只有 需要下载的 http,所以是  miniblink提供的API 是不能满足需求的。

还好,经过查看源码,有一个 wkeOnDownload2 函数,只是在 wke.cpp中存在,而在wke.h 中并没有提供出来,所以需要手动添加。这个接口。并且添加好接口后,还需要修改 miniblink 的源码。

添加接口与修改miniblink 源码的方法在如下:

1. 在wke.h 中 的 wkeDownloadCallback  下面添加如下代码,也就是添加 wkeDownload2Callback 回调函数的头文件。

typedef bool(WKE_CALL_TYPE*wkeDownloadCallback)(wkeWebView webView, void* param, const char* url);

typedef enum _wkeDownloadOpt {
	kWkeDownloadOptCancel,
	kWkeDownloadOptCacheData,
} wkeDownloadOpt;

typedef void* wkeNetJob;

typedef void(WKE_CALL_TYPE*wkeNetJobDataRecvCallback)(void* ptr, wkeNetJob job, const char* data, int length);
typedef void(WKE_CA
你提到的两行代码: ```c mosquitto_message_callback_set(mosq, message_callback); // 消息接收回调函数 mosquitto_subscribe_callback_set(mosq, subscribe_callback); // 订阅主题回调函数 ``` 这里有一个**关键误解**需要澄清: 👉 `mosquitto_subscribe_callback_set` 并不是“订阅主题回调函数”——这个说法是错误的,容易引起混淆。 下面我们详细解释这两个函数的真实作用、区别,并指出常见误区。 --- ### ✅ 正确理解:两个函数的作用 #### 1. `mosquitto_message_callback_set(mosq, message_callback);` - **功能**:设置一个回调函数,当客户端收到 MQTT 消息时被调用。 - 这是最常用的回调之一,用于处理从 broker 收到的发布消息(PUBLISH 报文)。 - 它属于 Mosquitto 的“标准异步接口”中的一部分。 ##### 示例: ```c void message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) { printf("Received on topic '%s': %.*s\n", message->topic, message->payloadlen, (char *)message->payload); } // 设置消息回调 mosquitto_message_callback_set(mosq, message_callback); ``` 📌 只要你订阅了某个主题,并且有消息发来,这个函数就会被触发。 --- #### 2. `mosquitto_subscribe_callback_set(mosq, subscribe_callback);` ⚠️ **这不是“订阅完成后的回调”!** - 实际上,这是 Mosquitto 提供的一个**高级简化接口(high-level interface)**,它会: - 自动设置内部的消息和连接回调; - 自动启动网络循环线程(`mosquitto_loop_start()`); - 将所有收到的消息都交给 `subscribe_callback` 处理; - 不需要手动管理事件循环。 > 所以它并不是“订阅行为完成后调用的回调”,而是“替代整个订阅+消息处理流程”的快捷方式。 ##### 示例: ```c void subscribe_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) { printf("Got message: %s -> %.*s\n", message->topic, message->payloadlen, (char*)message->payload); } // 启用高级模式:自动处理 loop 和消息分发 mosquitto_subscribe_callback_set(mosq, subscribe_callback); // 然后直接连接并订阅(无需再设 message_callback) mosquitto_connect(mosq, "localhost", 1883, 60); mosquitto_subscribe(mosq, NULL, "test/topic", 0); ``` 在这种模式下: - 你不能再使用 `mosquitto_message_callback_set`; - `subscribe_callback` 实际上等价于 `message_callback`; - 内部已经封装了完整的事件处理机制。 --- ### 🔍 核心区别总结 | 对比项 | `mosquitto_message_callback_set` | `mosquitto_subscribe_callback_set` | |--------|----------------------------------|------------------------------------| | 类型 | 标准回调设置函数 | 高级简化接口入口 | | 是否启用自动 loop | 否(需手动调用 `loop_start` 或 `loop_forever`) | 是(自动开启内部 loop) | | 使用场景 | 精细控制客户端行为(推荐生产环境) | 快速原型开发或简单测试 | | 能否与其它 callback 共存 | 可以(如 connect、disconnect 回调) | 不能(会覆盖其他回调) | | 回调函数用途 | 处理接收到的 PUBLISH 消息 | 同样是处理消息,但绑定的是高级模式 | --- ### ❌ 常见误解纠正 > ❌ “`subscribe_callback` 是在成功订阅后被调用的?” ➡️ **错误!** - 成功订阅后并不会触发用户定义的“订阅完成回调”。 - MQTT 协议中,客户端发送 `SUBSCRIBE`,broker 返回 `SUBACK`,Mosquitto 库可以通过 `subscribe_callback_v2`(v5+)或日志查看是否成功,但没有专门的“订阅成功回调”API。 - 如果你想知道订阅是否成功,应该监听 `on_subscribe` 回调(通过 `mosquitto_subscribe_callback_set` 不支持此功能)。 ✅ 正确做法(使用标准接口): ```c void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) { printf("Subscribed successfully with message ID: %d\n", mid); } mosquitto_subscribe_callback_set(mosq, NULL); // 不要用这个高级接口 mosquitto_subscribe_callbacks_set(mosq, on_connect, on_subscribe, on_message, ...); // 更细粒度控制 ``` --- ### ✅ 推荐使用方式(标准流程) ```c #include <mosquitto.h> #include <stdio.h> void on_connect(struct mosquitto *mosq, void *obj, int reason_code) { if (reason_code == 0) { mosquitto_subscribe(mosq, NULL, "device/rpc/request", 0); printf("Connected and subscribed.\n"); } } void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) { printf("Recv [%s]: %.*s\n", msg->topic, msg->payloadlen, (char*)msg->payload); } void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) { printf("Subscription confirmed (mid=%d)\n", mid); } int main() { mosquitto_lib_init(); struct mosquitto *mosq = mosquitto_new("sub-client", true, NULL); // 设置各个回调 mosquitto_connect_callback_set(mosq, on_connect); mosquitto_message_callback_set(mosq, on_message); mosquitto_subscribe_callbacks_set 不是标准函数 —— 实际上应使用以下组合 // 正确方式:通过 connect 后手动 subscribe,并利用 on_message 接收 mosquitto_connect(mosq, "localhost", 1883, 60); mosquitto_loop_start(mosq); getchar(); // keep running mosquitto_loop_stop(mosq, true); mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return 0; } ``` --- ###
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chen249191508

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值