You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

libcurl调用WriteFunction回调后保持Pushbullet流式连接持续运行

解决libcurl对接Pushbullet流式接口后连接自动关闭的问题

我来帮你搞定这个问题!你的代码里有两个核心问题导致回调触发后连接就关闭了,咱们一步步修正,让长连接稳定跑起来:

问题根源分析

  1. 回调函数签名不匹配:libcurl的CURLOPT_WRITEFUNCTION要求回调必须遵循固定签名,你当前的getwss_cb参数和返回值都不符合规范,这会让libcurl无法正确处理后续逻辑,直接终止连接。
  2. 回调未返回正确字节数:libcurl通过回调的返回值判断传输是否正常,如果返回0或错误值,它会认为出了问题,主动断开连接。

修正后的完整代码

#include <stdio.h>
#include <string.h>
#include <curl/curl.h>

// 符合libcurl要求的回调函数签名
size_t getwss_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
    // 计算实际接收的字节总数
    size_t total_bytes = size * nmemb;
    // 安全打印数据(流式数据不一定带\0终止符,用%.*s避免越界)
    printf("Received data: %.*s\n", (int)total_bytes, ptr);
    // 返回处理的字节数,告诉libcurl继续监听流
    return total_bytes;
}

int getwss(void) {
    CURL *easyhandle = curl_easy_init();
    if (!easyhandle) {
        fprintf(stderr, "初始化curl失败!\n");
        return 1;
    }

    // 替换为你的Pushbullet Access Token
    curl_easy_setopt(easyhandle, CURLOPT_URL, "https://stream.pushbullet.com/streaming/<access-token>");
    
    // 设置正确的回调函数
    curl_easy_setopt(easyhandle, CURLOPT_WRITEFUNCTION, getwss_cb);
    
    // 启用TCP保活,防止长期无数据时被防火墙/路由器断开
    curl_easy_setopt(easyhandle, CURLOPT_TCP_KEEPALIVE, 1L);
    curl_easy_setopt(easyhandle, CURLOPT_TCP_KEEPIDLE, 30L);  // 30秒后开始发保活包
    curl_easy_setopt(easyhandle, CURLOPT_TCP_KEEPINTVL, 10L); // 每10秒发一次保活包
    
    // 允许连接复用,避免每次断开后重新建立连接
    curl_easy_setopt(easyhandle, CURLOPT_FORBID_REUSE, 0L);
    
    // 执行请求,这个调用会一直阻塞直到连接主动断开或出错
    CURLcode res = curl_easy_perform(easyhandle);
    if (res != CURLE_OK) {
        fprintf(stderr, "请求失败:%s\n", curl_easy_strerror(res));
    }

    curl_easy_cleanup(easyhandle);
    return 0;
}

关键修改说明

  • 回调函数修正:用了libcurl要求的标准签名,返回实际处理的字节数,确保libcurl知道传输正常,继续保持连接。
  • TCP保活配置:添加了保活参数,防止长时间无数据时连接被中间网络设备强制断开,这对长连接场景非常重要。
  • 错误检查:增加了curl初始化的错误判断,避免空指针导致的崩溃。
  • 安全打印:用%.*s格式化输出,避免流式数据无终止符时的printf越界问题。

额外提示

  • 记得把代码里的<access-token>替换成你自己的Pushbullet有效令牌。
  • 如果需要优雅终止程序(比如按Ctrl+C),可以添加信号处理逻辑,调用curl_easy_cleanup来关闭连接。
  • curl_easy_perform会一直阻塞运行,直到连接断开或出现错误,这正是你需要的“持续监听”效果。

内容的提问来源于stack exchange,提问作者Rumesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:36:04