具有开放连接的服务器端 C++ http 侦听器。当客户端终止时,线程会发生什么?

问题描述 投票:0回答:1

我正在尝试使用 Cpp Rest SDK 实现带有事件的服务器开放 http 连接。我刚刚开始调查 CPP Rest。 我用了这个例子 实施:

MyServer::MyServer(utility::string_t url) : mListener(url)
{
  mListener.support(methods::GET, bind(&MyServer::handleGet, this, placeholders::_1));
}


void MyServer::handleGet(http_request iRequest)
{
  ucout << iRequest.to_string() << endl;

  http_response wResponse;

  // Setting headers
  wResponse.set_status_code(status_codes::OK);
  wResponse.headers().add(header_names::access_control_allow_origin, U("*"));
  wResponse.headers().add(header_names::content_type, U("text/event-stream"));

  // Preparing buffer
  streams::producer_consumer_buffer<char> wBuffer;
  streams::basic_istream<uint8_t> wStream(wBuffer);
  wResponse.set_body(wStream);

  auto wReplyTask = iRequest.reply(wResponse);

  wBuffer.putn_nocopy("data: a\n",10).wait();
  wBuffer.putn_nocopy("data: b\n\n",12).wait();
  wBuffer.sync().wait();  // seems equivalent to 'flush'

  this_thread::sleep_for(chrono::milliseconds(2000));

  wBuffer.putn_nocopy("data: c\n", 10).wait();
  wBuffer.putn_nocopy("data: d\n\n", 12).wait();
  wBuffer.sync().wait();
  // wBuffer.close(std::ios_base::out).wait();    // closes the connection
  wReplyTask.wait();      // blocking!
}

我在调试器中运行,我从未看到线程被终止。当客户端中止连接时,线程仍然坐在这里,正如我在调试器的 VS 线程窗口中看到的那样,等待后没有断点发生。 当客户端中止连接时,我正在考虑终止线程handleGet。我该怎么办?

通过来自多个客户端的连接以及 SDK 中关于 40 个线程限制的知识,我不确定如何正确终止库创建的线程。

c++ http server-sent-events cpprest-sdk
1个回答
0
投票

通过检查wReplyTask.is_done()解决了这个问题。删除了等待,并在循环中处理响应。当客户端中止连接时,is_done() 返回 true。功能齐全:

void MyServer::handleGet(http_request iRequest)
{
    ucout << iRequest.to_string() << endl;
    http_response wResponse;
    auto context = iRequest._get_server_context();

    // Setting headers
    wResponse.set_status_code(status_codes::OK);
    wResponse.headers().add(header_names::access_control_allow_origin, U("*"));
    wResponse.headers().add(header_names::content_type, U("text/event-stream"));

    // Preparing buffer
    streams::producer_consumer_buffer<char> wBuffer;
    streams::basic_istream<uint8_t> wStream(wBuffer);
    wResponse.set_body(wStream);

    auto wReplyTask = iRequest.reply(wResponse);// .then([this](pplx::task<void> t) { handle_error(t);  });

    wBuffer.putn_nocopy("id: 35\n", 7).wait();
    wBuffer.putn_nocopy("data: a\n", 8).wait();
    wBuffer.putn_nocopy("data: b\n\n", 9).wait();
    wBuffer.sync().wait();  // seems equivalent to 'flush'

    while (true)
    {
        this_thread::sleep_for(chrono::milliseconds(2000));
        
        if (wReplyTask.is_done())
        {
            wBuffer.close(std::ios_base::out).wait();
            return;
        }


        string datac = "data: c\n";
        wBuffer.putn_nocopy(datac.c_str(), datac.size()).wait();
        wBuffer.putn_nocopy("data: d\n\n", 9).wait();
        wBuffer.sync().wait();
    }


    // wBuffer.close(std::ios_base::out).wait();    // closes the connection
     //wReplyTask.wait();      // blocking!


}
© www.soinside.com 2019 - 2024. All rights reserved.