Boost 野兽 async_write 在多次调用中失败

问题描述 投票:0回答:1

我尝试使用 boost::beast::websocket::aysnc_write 进行多次调用,我对缓冲区进行了排队,并在写入结束时,在句柄中,我从队列中弹出并再次调用写入。我尝试通过 5 次调用来运行它,但在弹出第二个缓冲区后它停止运行。

我在1.72.0版本中使用Boost,linux rocky

void Session::do_write(std::string data)
{
  std::cout << "do_write" << std::endl;
  if (m_isWrite) {
    std::cout << "do_write push" << std::endl;
    m_queueBufferTx.push(boost::asio::buffer(data));
    return;
  }
  m_bufferTx = boost::asio::buffer(data);
  on_write();
}

void Session::on_write()
{
  std::cout << "write size " <<m_queueBufferTx.size() << std::endl;
  m_isWrite = true;
  m_ws.text(m_ws.got_text());
  m_ws.async_write(m_bufferTx, beast::bind_front_handler(&Session::handle_write, shared_from_this()));
}

void Session::handle_write(beast::error_code ec, std::size_t bytes_transferred)
{
   m_isWrite = false;
   std::cout << "finish write size " <<m_queueBufferTx.size() << std::endl;
   boost::ignore_unused(bytes_transferred);
   if (ec) {
     LOGGER(MtLogger::ERROR, "write: " << ec.message() << "\n")
     return;
   }
   if (!m_queueBufferTx.empty() && !m_isWrite) {
     std::cout << "handle_write pop" << std::endl;
     m_isWrite = true;
     m_bufferTx = m_queueBufferTx.pop();
     on_write();
   }
}

我主要做的是:

json ex = { { "type", "X400FeCmd" }, { "command", "Disconnection"} };
for (int i = 0; i < 5; ++i){
   session->do_write(ex.dump());
}

在终端中,我看到打印内容: 做_写

write size 0
do_write
do_write push
do_write
do_write push
do_write
do_write push
do_write
do_write push
finish write size 4
handle_write pop
write size 3
c++ websocket boost boost-asio boost-beast
1个回答
0
投票

我认为问题隐藏在这两者之间的相互作用中:

  if (m_isWrite) {
    std::cout << "do_write push" << std::endl;
    m_queueBufferTx.push(boost::asio::buffer(data));
    return;
  }

还有这个:

  std::cout << "write size " <<m_queueBufferTx.size() << std::endl;
  m_isWrite = true;

当你等待时

m_ws.async_write(m_bufferTx, beast::bind_front_handler(&Session::handle_write, shared_from_this()));

为了完成,你的外循环设法再调用

do_write
4 次。完成处理程序
handle_write
仅在事后执行,此时已经为时已晚。您可以使用例如
boost::asio::deadline_timer
来验证它是否在循环中添加延迟。我不完全理解
m_isWrite
的需要,只需检查你的缓冲区是否有东西并弹出它的内容。

© www.soinside.com 2019 - 2024. All rights reserved.