2

I have just now updated the boost library from 1.68.0 to 1.70.0 to get the timeouts operations in (beast) websocket ssl client async example.

In the above link you will see:

void
    on_resolve(
        beast::error_code ec,
        tcp::resolver::results_type results)
    {
        if(ec)
            return fail(ec, "resolve");

        // Set a timeout on the operation
        beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));

        // Make the connection on the IP address we get from a lookup
        beast::get_lowest_layer(ws_).async_connect(
            results,
            beast::bind_front_handler(
                &session::on_connect,
                shared_from_this()));
    }

There are more than one function which is using this structure for the timeouts. And for my code (in eclipse-cdt I see it like this

Screenshot for this

The error says (when mouse pointer hovers on the expires_after or async_connect):

Method 'expires_after' could not be resolved
OR
Method 'async_connect' could not be resolved

and when the mouse pointer is taken over "get_lowest_layer", the error says

Invalid arguments '
Candidates are:
boost::beast::detail::lowest_layer_type_impl<#0,bool74 0 value 43 8 2 201 2
boost::beast::detail::has_next_layer_impl
boost::beast::detail::has_next_layer_impl 1 #0 0 71 4417 0 0>::type & get_lowest_layer(#0 &) '

I am wondering I need to link some library for this. I can't figure out which one. Any suggestions?

4
  • Did you try the obvious, Clean and Rebuild of the example app? Pretty sure Boost uses headers-only, because distributing libraries is like, just wild and crazy. Commented Apr 16, 2019 at 13:15
  • @ChrisO I did! No luck though. I am wondering if I missed linking with appropriate ‘*.so’ Commented Apr 16, 2019 at 13:18
  • Does the example compile and link correctly for you? Commented Apr 19, 2019 at 1:18
  • 1
    Hi @VinnieFalco Yes it compiles and links correctly. The issue is solved though, please see the answer for how I did it. It is working fine now. Also please let me know,if there is a better way Commented Apr 19, 2019 at 4:08

2 Answers 2

1

This has nothing to do with so libraries.

  1. boost::beast is a template library, so no shared libraries.

  2. Your editor uses definitions, not linking, to show this IDE errors. Basically your editor failed at finding the headers you're pointing at.

If I have to guess, you have compiled boost manually to use boost::beast, because it's not available on most modern Linux distributions. Or you're probably not using Linux. The example has some includes, and your IDE is failing to resolve them because they're not in your system includes (/usr/include). So, it doesn't know where to look.

So, in conclusion, your build system is not coupled correctly with your IDE.

To solve the problem, try to understand how your IDE resolves missing headers. Add the include path that has the boost headers to it.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi Quantum! l am pretty sure that the include path is pointing at the right place. But since beast is a boost library, and some of the libraries need to linked (boost_thread, boost_filesystem etc), so I thought may be beast is internally dependent on other boost library component which might needed linking. Although I know beast is a header library.
Also all the #include are able to find the required library.
@RC0993 It's not only the include path, but the includes in includes, which is why I mentioned specifying include directories for your IDE. Again, it's DEFINITELY no a "library" (so file). It's all about includes. Libraries are only requires when building. If this boost comes with your system, install all boost libs. On Ubuntu and Debian with sudo apt-get install libboost-all-dev. If you downloaded them manually, then I'm sure it's an include path problem.
0

I have solved the problem in in my code (with beast 1.70.0) by setting the timeout as

void
    on_resolve(
        beast::error_code ec,
        tcp::resolver::results_type results)
    {
        if(ec)
            return fail(ec, "resolve");

        // Set a timeout on the operation
        ws_.next_layer().expires_after(std::chrono::seconds(30));

        // Make the connection on the IP address we get from a lookup
         ws_.next_layer().async_connect(
            results,
            beast::bind_front_handler(
                &session::on_connect,
                shared_from_this()));
    }

I have also made some changes in my code (with beast 1.68.0) as follows

void Foo::closetimer_websocket(beast::error_code ec) {

    if (ec.message() == "Success") {
        ioc.stop();
    }
}

// closetimer_websocket is the member of class Foo. And FooObject is its instance
void session::SetAsyncOpTimeoutInSec(unsigned int time_inSeconds) {
    TcpTimer.expires_from_now((boost::posix_time::seconds(time_inSeconds)));
    TcpTimer.async_wait(bind(&Foo::closetimer_websocket, FooObject, placeholders::_1));
}

void session::on_resolve(beast::error_code ec,
        tcp::resolver::results_type results) {
     if(ec)
            return fail(ec, "resolve");

    //Set the timeout
    SetAsyncOpTimeoutInSec(5);

    // Make the connection on the IP address we get from a lookup
    net::async_connect(ws_.next_layer().next_layer(), results.begin(),
            results.end(),
            bind(&session::on_connect, shared_from_this(), placeholders::_1));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.