我正在尝试使用 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 个线程限制的知识,我不确定如何正确终止库创建的线程。
通过检查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!
}