'Boost Beast async_write() With Queue
I have the following code:
std::queue< nlohmann::json > outgoingMessages;
void session::do_write( void ) {
if ( outgoingMessages.size() > 0 ) {
auto message = outgoingMessages.front();
outgoingMessages.pop();
ws_.async_write( boost::asio::buffer( message.dump() ), boost::beast::bind_front_handler( & session::on_write, shared_from_this() ) );
}
};
void session::on_write( boost::beast::error_code errorCode, std::size_t bytes_transferred ) {
if ( errorCode )
return fail( errorCode, "write" );
if ( bytes_transferred == 0 )
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
do_write();
};
What I need it to do is only write when there is data to write. The problem is, when the queue is empty, async_write()
never gets called, breaking the loop. Works great until it runs out of queue items to send.
Solution 1:[1]
I had the same issue and fixed it by recursively calling do_write()
and check wether or not the queue contains new items. As long as you are making sure that async_write()
is not called concurrently, you should be fine.
Try changing your code to:
std::queue< nlohmann::json > outgoingMessages;
bool isWriting = false;
void session::do_write( void ) {
if ( !isWriting && outgoingMessages.size() > 0 ) {
isWriting = true;
auto message = outgoingMessages.front();
ws_.async_write( boost::asio::buffer( outgoingMessages.dump() ), boost::beast::bind_front_handler( & session::on_write, shared_from_this() ) );
} else
{
// Repeat write
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
do_write();
};
void session::on_write( boost::beast::error_code errorCode, std::size_t bytes_transferred ) {
if ( errorCode )
return fail( errorCode, "write" );
if ( bytes_transferred == 0 )
std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) );
outgoingMessages.pop();
// Repeat write for additional messages
if (!outgoingMessages.empty())
{
ws_.async_write(
boost::asio::buffer(outgoingMessages.front()),
beast::bind_front_handler(
&session::on_write,
shared_from_this()));
}
else
{
isWriting = false;
do_write();
}
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | oerol |