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

Cpp Rest SDK HTTP长连接客户端断开后如何终止阻塞线程

解决Cpp Rest SDK SSE服务器客户端断开后线程阻塞的问题

问题根源

Cpp Rest SDK的http_listener默认不会在客户端断开连接时自动取消未完成的异步操作,导致你在wReplyTask.wait()处永久阻塞,占用线程池资源(默认上限40)。

具体解决方案

  1. 监听连接关闭事件
    每个请求的响应对象可以绑定on_close回调,当客户端主动断开时触发,在回调中取消对应的异步推送任务。

  2. 替换阻塞式wait()为异步任务链
    避免用wait()阻塞线程,改用pplx::task的异步链式调用,配合取消机制让线程能正常回收。

示例代码

void handleGet(http_request request)
{
    // 构造SSE响应头
    auto response = request.create_response(status_codes::OK);
    response.headers().add(U("Content-Type"), U("text/event-stream"));
    response.headers().add(U("Cache-Control"), U("no-cache"));
    response.headers().add(U("Connection"), U("keep-alive"));

    pplx::task<void> pushTask;
    // 绑定连接关闭回调,触发时取消推送任务
    auto closeRegistration = response.on_close([&pushTask]() {
        pushTask.cancel();
    });

    // 异步执行事件推送逻辑
    pushTask = pplx::create_task([&response]() {
        try {
            while (true) {
                // 生成SSE格式数据
                std::wstring sseData = U("data: new event\n\n");
                response.write(to_string_t(sseData));
                
                // 等待期间允许被取消
                pplx::wait(1000).wait();
            }
        }
        catch (const pplx::task_canceled&) {
            // 捕获取消异常,正常退出循环
        }
    });

    // 异步完成响应,避免阻塞线程
    response.complete().then([closeRegistration](pplx::task<void> t) {
        try {
            t.get();
        }
        catch (const std::exception& e) {
            // 处理响应完成时的异常
        }
    });
}

额外注意事项

  • 所有异步任务必须能被正确取消,确保线程不会被永久占用
  • 不要在请求处理函数中使用阻塞式调用,尽量用then()回调处理后续逻辑,让SDK线程池高效复用线程
  • 可以维护一个全局的客户端连接集合,在on_close回调中移除对应条目,方便统一管理活跃连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:52:35