1

I'm currently trying to read data from websocket which takes user input. At the same time, I also write data to the websocket. It used to work when I only write data to the websocket. However, the program seems to halt when I try to read and write to websocket. The following is the code that I've tried.

                if(!messageQ.empty())
                {   
                    //if (recvbuf.ch_idx == 1)
                    //cout << "Ws Write " << gs32cnt1 << endl;  
                    boost::beast::flat_buffer buffer;
                    ws_.write(net::buffer(*messageQ.front()));
                    ws_.read(buffer);
                    cout << "ws Read " << endl; 
                    auto out = boost::beast::buffers_to_string(buffer.cdata());
                    string stringVal;
                    stringVal = out;
                    std::cout<<"stringVal = "<<stringVal<<std::endl;

                    //printf("BAAAM! %d\n", m_count_objects);
                    messageQ.pop_back();

As you can see it, I call 'read' method right after 'write' method. This doesn't seem right anymore. Can any wise websocket guru lend me a helping hand? Thanks in advance!

Taki
  • 313
  • 4
  • 13

1 Answers1

0

You can use the async versions. There are many examples on this site:

In your particular snippet, there is no simple transformation that would be useful, e.g.

struct X {
    void foo() {
        if (!messageQ.empty()) {
            auto w = ws_.async_write(net::buffer(messageQ.front()), net::use_future);

            boost::beast::flat_buffer buffer;
            auto r = ws_.async_read(buffer, net::use_future);
            r.wait();
            std::cout << "stringVal = " << beast::buffers_to_string(buffer.cdata()) << std::endl;

            // printf("BAAAM! %d\n", m_count_objects);
            w.wait();
            messageQ.pop_back();
        }
    }

    // std::deque<http::request<http::string_body>> messageQ;
    std::deque<std::string>        messageQ;

    net::thread_pool               ioc_{1};
    websocket::stream<tcp::socket> ws_{ioc_};

    ~X() { ioc_.join(); }
};

What you really need is the usual pattern

"The "best practice" approach would always keep an async read pending to detect disconnects early. This requires you to go back to doing all IO asynchronously."

This is quoted from this other answer, where I showed that on a BitMex client: Boost Beast, Handshake, Keep-Alive

Note that this was after posting an answer with purely synchronous code that had some limitation. You're likely in a very similar situation, so perhaps reading that answer will help you along.

sehe
  • 374,641
  • 47
  • 450
  • 633