我正在实现一个访问REST端点的客户端,然后开始处理SSE stream并监视事件发生的时间。为此,我使用Boost :: Beast版本124和Boost 1.63并尝试使用async_read_some
逐步读取响应的主体。
到目前为止,这是我的代码:
namespace http = boost::beast::http;
http::response_parser<http::string_body> sse_client::m_parser;
http::response<http::string_body> sse_client::m_response;
boost::beast::flat_buffer m_buffer;
void sse_client::monitor_sse()
{
http::request<http::empty_body> req{http::verb::get, m_target, 11};
req.set(http::field::host, m_host);
req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
req.set(http::field::accept, "text/event-stream");
http::async_write(m_socket, req,
std::bind(
&sse_client::process_sse,
shared_from_this(),
std::placeholders::_1,
std::placeholders::_2));
}
void sse_client::process_sse(boost::system::error_code ec, std::size_t byte_count)
{
http::read_header(m_socket, m_buffer, m_parser);
http::async_read_some(m_socket, m_buffer, m_parser,
std::bind(
&sse_client::read_event,
shared_from_this(),
std::placeholders::_1));
}
void sse_client::read_event(boost::system::error_code ec)
{
// TODO: process event
http::async_read_some(m_socket, m_buffer, m_parser,
std::bind(
&sse_client::read_event,
shared_from_this(),
std::placeholders::_1));
}
我的问题是:
response_parser
和response
与http::string_body
相比,是否有更合适的类型?read_event
处理程序时,它如何访问async_read_some
检索到的内容?它应该从缓冲区中拉出来吗?答案 0 :(得分:2)
我先回答您的问题,然后提供解释。
是的,你想读取标题,然后调用read_some(或read,见下文),直到解析器从is_complete()返回true。但是,在您的代码中,我注意到您正在混合同步和异步调用(read_header后跟async_read_some)。最好只坚持一个模型而不是混合它们。
出于您的目的,您可能需要buffer_body而不是string_body。文档中有一个示例,说明如何执行此操作(http://www.boost.org/doc/libs/1_66_0/libs/beast/doc/html/beast/using_http/parser_stream_operations/incremental_read.html)
&#34;缓冲区&#34;你引用的是传递给HTTP流操作的动态缓冲区参数。虽然此缓冲区将保留消息数据,但不应由应用程序进行检查。此缓冲区用于保存流算法可以读取的当前消息末尾的其他数据(这在http://www.boost.org/doc/libs/1_66_0/libs/beast/doc/html/beast/using_http/message_stream_operations.html#beast.using_http.message_stream_operations.reading中有说明)。您将在使用buffer_body
http :: response_parser :: get()将为您提供对正在读取的消息的访问权。
最好的解决方案是在示例中使用buffer_body,提供一个内存区域指向它,然后在循环中调用read或async_read。每次缓冲区已满时,读取将返回错误beast::http::error::need_buffer
,表示需要进一步调用。
希望这有帮助!