野兽 async_read() 是如何工作的?有啥选择吗?

Posted

技术标签:

【中文标题】野兽 async_read() 是如何工作的?有啥选择吗?【英文标题】:How does beast async_read() work & is there an option for it?野兽 async_read() 是如何工作的?有什么选择吗? 【发布时间】:2019-04-05 07:52:36 【问题描述】:

我对@9​​87654322@ 的基础知识不是很熟悉。我正在处理一项已连接到 Web 服务器并读取响应的任务。响应在随机周期内抛出,在响应生成时。

为此,我正在使用 boost::beast 库,它包含在 boost::asio 基础之上。

我发现async_read() 函数正在等待,直到它收到响应。

现在,事情是:在documentations & example 中,websocket 通信的异步方式显示在 websocket 收到响应后关闭的位置。

这是由此代码(野兽文档)完成的:

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));

在这个程序中,假设发送在接收之前完成。并且只有一次响应来自服务器的期望。之后,它(客户端)继续前进并关闭 websocket。

但是在我的程序中

我必须检查写入部分是否已经结束,如果没有,则在写入过程中 websocket 应该来检查到目前为止所写内容的响应。

现在,我放了一个 if else 来告诉我的程序我的写作是否完成?如果没有,那么程序应该回到写入部分并编写所需的东西。如果是,则关闭连接。

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

现在我要做的是写入完成后等待3秒,每1秒读取一次websocket,3秒后关闭websocket。

为此,我添加了一个 if else 以检查 read_resp 的 3 秒条件

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));
    

但是 websocket 正在等待 async-read 接收某些东西,这样做只会进入会话超时。

如何仅查看是否有要读取的内容,然后继续执行回调?

【问题讨论】:

【参考方案1】:

这可能只是我的问题的答案。我无法保证为未来的读者提供解决方案。

我已经删除了read_resp() 自循环,只是让async_read()write_completed == true 时移动到close_ws_

async_read 只要收到响应就会等待,不会继续下一步,从而导致超时。

【讨论】:

以上是关于野兽 async_read() 是如何工作的?有啥选择吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在到达终止字符时返回 boost::asio::async_read

boost::asio::async_read 无限循环,接收数据为零字节

如何使用超时创建 boost::async_read 和 async_write

boost::asio::async_read 不回调我的处理函数

最大大小的 async_read()

当 streambuf 由先前的 async_read 填充时, boost::asio::async_read 进入 boost::asio::streambuf 块