如何使用cpp-httplib实现Server-Sent Event服务器持续订阅
cpp-httplib是否具备与CURL类似的SSE持续订阅能力?
问题背景
我现有一段使用CURL的C++代码,可完美订阅Server-Sent Event(SSE)服务器,能实时接收服务器产生的事件,代码如下:
#include <iostream> #include <curl/curl.h> // Callback function to handle SSE events size_t handle_event_data(void* buffer, size_t size, size_t nmemb, void* user_data) { // Process and handle the SSE event data here std::string event_data(static_cast<char*>(buffer), size * nmemb); std::cout << "Received event: " << event_data << std::endl; return size * nmemb; } int main() { CURL* curl; CURLcode res; curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if (curl) { // Set the SSE server URL curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:1234/event1"); // Set the callback function to handle SSE events curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle_event_data); // Perform the SSE request res = curl_easy_perform(curl); if (res != CURLE_OK) { std::cerr << "Failed to connect to SSE server: " << curl_easy_strerror(res) << std::endl; } curl_easy_cleanup(curl); } else { std::cerr << "Failed to initialize libcurl" << std::endl; } curl_global_cleanup(); return 0; }
该代码可稳定订阅服务器并实时接收事件。但我尝试使用cpp-httplib实现相同功能时,编写的代码在接收第一条数据后即退出,代码如下:
#include <httplib.h> #include <iostream> using namespace std; int main(void) { httplib::Client("http://localhost:1234") .Get("/event1", [&](const char *data, size_t data_length) { std::cout << string(data, data_length); return true; }); return 0; }
解答
cpp-httplib具备与CURL类似的SSE持续订阅能力,你遇到的问题是代码写法导致的:
你创建了临时的httplib::Client对象,在Get方法调用完成后,这个临时对象会被立即销毁,进而提前关闭了与SSE服务器的连接,因此只能接收到第一条数据。
修正后的代码
只需创建一个持久化的Client对象,确保在订阅期间对象保持存活,同时可以设置无超时(适配SSE长期连接的特性):
#include <httplib.h> #include <iostream> #include <string> using namespace std; int main(void) { // 创建持久化的Client对象 httplib::Client cli("http://localhost:1234"); // 设置超时为0,表示无超时,避免因长时间无数据断开连接 cli.set_timeout(0); // 发起SSE请求,回调返回true表示继续接收后续数据 auto res = cli.Get("/event1", [&](const char *data, size_t data_length) { std::cout << string(data, data_length); return true; }); // 处理请求失败的情况 if (!res) { std::cerr << "请求失败: " << httplib::to_string(res.error()) << std::endl; } return 0; }
关键说明
- 持久化Client对象:必须保证
Client在整个订阅周期内存在,不能用临时对象调用Get方法。 - 回调返回值:回调函数返回
true时,cpp-httplib会继续监听并接收后续的SSE事件数据;若返回false则会终止连接。 - 超时设置:SSE是长期连接,设置
set_timeout(0)可以避免因服务器长时间未发送数据而触发超时断开。 - 分块传输支持:cpp-httplib默认支持HTTP分块传输编码(SSE依赖此特性),只要服务器正确返回分块格式的响应,就能持续接收事件。
内容的提问来源于stack exchange,提问作者shashashamti2008
相关产品推荐
相关产品推荐

