简体   繁体   中英

Boost-Beast async web socket Server-Client async read-write not writing output on console

I am trying out Boost Beast examples for asynchronous web socket server - client

I am running server and client as below,

server.exe 127.0.0.1 4242 1

client.exe 127.0.0.1 4242 "Hello"

If everything works I believe it should print "Hello" on server command prompt

Below is the code

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

        std::cout << "writing received value " << std::endl;
        ws_.async_write(
            buffer_.data(),
            beast::bind_front_handler(
            &session::on_write,
            shared_from_this()));

        std::cout << buffer_.data().data()<< std::endl;
    }

ws_.write() is not writing anything on console , however buffer_data.data() renders 00000163E044EE80

How do I make sure this is working fine? How do I retrieve string value from the socket buffer?

The line printing content of sent message should be placed before async_write :

    std::cout << buffer_.data().data()<< std::endl;

    ws_.async_write(
        buffer_.data(),
        beast::bind_front_handler(
        &session::on_write,
        shared_from_this()));

Why?

All functions from BOOST-ASIO/BEAST which start with async_ ALWAYS return immediately. They initate some task, which are performed in background asio core, and when they are ready, handlers are called.

Look at on_write handler:

void
    on_write(
        beast::error_code ec,
        std::size_t bytes_transferred)
{
    boost::ignore_unused(bytes_transferred);

    if (ec)
        return fail(ec, "write");

    // Clear the buffer
    buffer_.consume(buffer_.size());  /// <---

consume removes block of bytes whose length is buffer_size from the beginning of buffer_ .

Your problem is that buffer probably has been cleared and then it is printed:

thread 1             thread 2
------------------------------   | steps
  async_write      |             | [1]
                   |  consume    | [2]
  cout << buffer_  |             | [3]
                                 | 

In addition to using buffer before its consumed, in order to convert buffer I had to write to_string_ function which takes flat buffer and returns the string

std::string to_string_(beast::flat_buffer const& buffer)
{
    return std::string(boost::asio::buffer_cast<char const*>(
        beast::buffers_front(buffer.data())),
        boost::asio::buffer_size(buffer.data()));
};

Found out this can easily be done by beast::buffers_to_string(buffer_.data()) too.

Reference : trying-to-understand-the-boostbeast-multibuffer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM