How does beast async_read() work & is there an option for it?

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-24 10:55:16

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!