boost::beast 同步 http 客户端超时

Timeout for boost::beast sync http client

我正在改编synchronous HTTP client from the Boost Beast examples。不幸的是,示例客户端不包括超时选项,有时会卡在我的工作负载中。我尝试使用

添加超时
beast::get_lowest_layer(stream).expires_after(NetworkSettings::BASIC_TIMEOUT);

在调用 write/read 操作之前,但这些操作似乎只有在使用 async_read/write 时才有效。 From what I found,似乎基本的 boost asio 只支持异步操作的超时。所以我的问题是 beast 是否有能力在阻塞 connect/read/write 调用上使用超时。

你可以使用类似这样的东西。

尝试将 stream.connect(results) 更改为

auto Future = stream.async_connect(endpoint, net::use_future);
if(Future.wait_for(std::chrono::seconds(1)) == std::future_status::timeout){

   std::cout<<"timed_out";
   ....
}else {

}

一堆注意事项:

1)您可能需要以下头文件

#include<boost/asio/use_future.hpp>
#include<chrono>
#include<future>

2) 因为你是 asyc_* 发起的;你需要打电话给 ioc.run();

3) 你需要另一个线程来执行 ioc.run(); 因为我们正在通过异步模拟同步——有人必须 运行 event-loop.

另一种方法:您可以使用其本机句柄显式设置套接字选项(我从未这样做过)。但在此之前,请阅读此答案

const int timeout = 200;
::setsockopt(socket.native_handle(), SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof timeout);//SO_SNDTIMEO for send ops

https://linux.die.net/man/7/socket

SO_RCVTIMEO and SO_SNDTIMEO Specify the receiving or sending timeouts until reporting an error. The argument is a struct timeval. If an input or output function blocks for this period of time, and data has been sent or received, the return value of that function will be the amount of data transferred; if no data has been transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK, or EINPROGRESS (for connect(2)) just as if the socket was specified to be nonblocking. If the timeout is set to zero (the default) then the operation will never timeout. Timeouts only have effect for system calls that perform socket I/O (e.g., read(2), recvmsg(2), send(2), sendmsg(2)); timeouts have no effect for select(2), poll(2), epoll_wait(2), and so on.

超时不适用于 Asio 中的同步 I/O。由于 Beast 是 asio 之上的一层,它也不支持同步 I/O 的超时。如果你想要超时,你必须使用异步 API。您可以使用堆栈协程,或者如果您有足够现代的编译器,您可以尝试使用无堆栈协程 (co_await)。这些允许您编写看似同步但使用异步接口的代码。

Beast 文档对此很清楚: "For portability reasons, networking does not provide timeouts or cancellation features for synchronous stream operations."

https://www.boost.org/doc/libs/1_70_0/libs/beast/doc/html/beast/using_io/timeouts.html

如果您希望连接操作超时,请使用 beast::tcp_stream 的实例并调用 async_connect 成员函数: https://www.boost.org/doc/libs/1_70_0/libs/beast/doc/html/beast/using_io/timeouts.html#beast.using_io.timeouts.connecting