我在我的项目中使用 boost websocket 并坚持使用这段代码,其中我的 async_write 仅当它从客户端读取某些内容时才执行。
我使用了来自 websocket_server_async
的代码下面是代码
void do_read()
{
// Read a message into our buffer
ws_.async_read(
buffer_,
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
}
void on_read(beast::error_code ec, std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
// This indicates that the session was closed
if(ec == websocket::error::closed)
return;
if(ec)
fail(ec, "read");
// Echo the message
ws_.text(ws_.got_text());
ws_.async_write(
buffer_.data(),
beast::bind_front_handler(
&session::on_write,
shared_from_this()));
}
这里,由于 async_write 是在
on_read
函数中编写的,因此仅当从客户端发送某些内容时才会执行。但是我怎样才能不依赖于读取执行而连续向客户端写入消息
我尝试添加一个写入标志(每当需要向客户端发送数据时)并仅使用
ws_.write
代替asyn_write
(这是正确的方法吗)。
void do_read()
{
// Read a message into our buffer
ws_.async_read(
client_buffer_,
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
if(write_flag)
{
do_write();
}
}
void do_write()
{
ws_.write(net::buffer(server_buffer_));
write_flag = false;
//Do another read
do_read();
}
void on_read(beast::error_code ec, std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
// This indicates that the session was closed
if(ec == websocket::error::closed)
return;
if(ec)
fail(ec, "read");
//Do another read
do_read();
}
你想让它独立。添加写入标志确实没有帮助。
而是让它字面上独立:
do_read_loop() {
async_read(ws_, buf_, [this, self=shared_from_this](error_code ec, size_t bytes_transferred) {
// ...
if (!ec)
do_read_loop();
});
}
在写入方面,您希望相同,只是有时可能没有任何内容可发送。
std::deque<std::string> outbox_;
do_write_loop() {
if (outbox_.empty())
return;
async_write(ws_, asio::buffer(outbox_.front()), [this, self=shared_from_this](error_code ec, size_t bytes_transferred) {
// ...
if (!ec) {
outbox_.pop_front();
do_write_loop();
}
});
}
就是这样。它几乎完全对称,并且完全独立。唯一缺少的部分是何时启动写循环。
void send(std::string message) {
outbox_.push_back(std::move(message));
if (outbox_.size() == 1)
do_write_loop();
}
为了简单起见,我省略了股线(你的问题也没有提到它们)。如果您需要它们,您必须确保相关操作已完成:
void send(std::string msg) { asio::post(ws_.get_executor(), [this, self = shared_from_this(), m = std::move(msg)]() mutable { do_send(std::move(m)); }); }