问题
I am not very familiar with the boost::asio
fundamentals. I am working on a task where I have connected to a web server and reading the response. The response is thrown at a random period, i.e. as and when the response is generated.
For this I am using the boost::beast
library which is wrapped over the boost::asio
fundamentals.
I have found that the async_read()
function is waiting until it is receiving a response.
Now, the thing is : in documentations & example the asynchronous way of websocket communication is shown where the websocket is closed after it receives the response.
that is accomplished by this code (beast docs):
void read_resp(boost::system::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "write");
// Read a message into our buffer
ws_.async_read(buffer_, std::bind(&session::close_ws_, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
void close_ws_(boost::system::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "read");
// Close the WebSocket connection
ws_.async_close(websocket::close_code::normal, std::bind(&session::on_close, shared_from_this(), std::placeholders::_1));
}
In this program it is assumed that the sending is completed before receiving. And there is only once response to expect from server. After which, it(client) goes forward and closes the websocket.
But in my program:
I have to check whether the writing part has ended, if not, while the writing is in progress the websocket should come and check the response for whatever is written till now.
Now for this, I have put an if else which will tell my program whether or not my writing is compeleted or not? if not, then the program should go back to the write section and write the required thing. If Yes then go and close the connection.
void write_bytes(//Some parameters) {
//write on websocket
//go to read_resp
}
void read_resp(boost::system::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "write");
// Read a message into our buffer
if (write_completed){
ws_.async_read(buffer_, std::bind(&session::close_ws_, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
} else {
ws_.async_read(buffer_, std::bind(&session::write_bytes, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
}
void close_ws_(//Some parameters) {
//Same as before
}
Now what I want to do is,After the write is completed wait for 3 seconds and read the websocket after every 1 second, and after 3rd second go to close the websocket.
For that I have included one more if else to check the 3 second condition to the read_resp
void read_resp(boost::system::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if(ec)
return fail(ec, "write");
// Read a message into our buffer
if (write_completed){
if (3_seconds_completed) {
ws_.async_read(buffer_, std::bind(&session::close_ws_, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
} else {
usleep(1000000); //wait for a second
ws_.async_read(buffer_, std::bind(&session::read_resp, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
} else {
ws_.async_read(buffer_, std::bind(&session::write_bytes, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
}
But the websocket is waiting for async-read
to receive something and in doing so it just goes to session timeout.
how can just just see if something is there to read and then move on to execute the call back?
回答1:
This might just be an answer for my problem here. I can't guarentee the solution for future readers.
I have removed the read_resp()
self-loop and simply let the async_read()
to move to close_ws_
when write_completed == true
.
The async_read will wait for as long as it receives the response and do not move on to next step thus causing the timeout.
来源:https://stackoverflow.com/questions/55530669/how-does-beast-async-read-work-is-there-an-option-for-it