我正在使用计时器和 async_read,因此每当计时器耗尽时,它就会通过执行 ws_.next_layer().cancel() 取消 async_read,以便我可以继续下一个操作。但是当我捕获超时错误并继续下一个写入操作 ws_.write() 时,我收到操作取消错误。 ws_.next_layer().cancel() 是否会使套接字无法用于后续操作。 是否有其他替代方法来捕获空闲超时并从 async_read 退出,同时仍然保持套接字功能而无需关闭并重新连接它。
#include "Socket_Factory_1.h"
class TimeoutException : public std::exception {
public:
explicit TimeoutException(const std::string& message) : message_(message) {}
virtual const char* what() const noexcept override {
return message_.c_str();
}
private:
std::string message_;
};
WebSocketClient::WebSocketClient(const std::string& host, const std::string& port)
: host_(host), port_(port), ioc_(), resolver_(ioc_), ws_(ioc_), timer_(ioc_) {}
WebSocketClient::~WebSocketClient() {
close();
}
void WebSocketClient::connect() {
try {
ws_.binary(true);
auto const results = resolver_.resolve(host_, port_);
asio::connect(ws_.next_layer(), results.begin(), results.end());
ws_.handshake(host_, "/");
} catch (const std::exception& e) {
std::cerr << "Connect Error: " << e.what() << std::endl;
throw;
}
}
void WebSocketClient::send(const void* data, size_t size) {
try {
ws_.write(asio::buffer(data, size));
} catch (const std::exception& e) {
std::cerr << "Send Error: " << e.what() << std::endl;
throw;
}
}
std::string WebSocketClient::receive() {
std::cout<<"HI1";
read_successful = false;
timeout_occurred = false;
// Set up the timer
std::chrono::seconds timeout_duration(3);
timer_.expires_after(timeout_duration);
std::cout<<"HI";
// Start an asynchronous read operation
ws_.async_read(buffer,
[this](beast::error_code ec, std::size_t bytes_transferred) {
if (!ec) {
result = beast::buffers_to_string(buffer.data());
read_successful = true; // Mark read as successful
}
else if(ec==asio::error::operation_aborted){
std::cout<<"aborted"<<std::endl;
}
else {
std::cerr << "Read Error: " << ec.message() << std::endl;
}
}
);
// Set up the timeout handler
timer_.async_wait(
[this](beast::error_code ec) {
if (ec != asio::error::operation_aborted) {
timeout_occurred = true; // Mark timeout as occurred
}else{
std::cout<<"aborted tiemr"<<std::endl;
}
}
);
// Run the IO context to perform the asynchronous operations
while (!read_successful && !timeout_occurred) {
ioc_.run_one(); // Process one ready handler
}
buffer.clear();
if (timeout_occurred) {
ws_.next_layer().cancel();
ioc_.run();
// ioc_.restart();
std::cerr << "Read operation timed out\n";
throw TimeoutException("Timeout");
}
if (read_successful) {
timer_.cancel();
return result;
}
return ""; // Return empty string if neither read nor timeout occurred
}
void WebSocketClient::close() {
try {
if (ws_.is_open()) {
ws_.close(websocket::close_code::normal);
}
} catch (const std::exception& e) {
std::cerr << "Close Error: " << e.what() << std::endl;
}
}
我正在尝试实现空闲超时,以便代码从 async_read 的无限循环中退出
ws_.next_layer().cancel()是否
你必须假设同样多的事情。文档说例如
每次操作取消
该异步操作支持取消以下操作
值:net::cancellation_type
- net::cancellation_type::terminal
- 网络::取消类型::总计
如果因以下原因暂停操作,则完全取消成功 持续的控制操作,例如乒乓球。
底层支持时终端取消成功 流。
终端取消使流处于未定义状态,因此 只有关闭它才保证成功。
由于您不能保证全部取消,所以您必须假设终点站取消,这意味着您只能关闭运输。
您可能应该在应用程序层实现应用程序逻辑。例如。有一个传出队列并停止写循环,而不是在底层流上硬取消操作。