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?

RC0993
  • 898
  • 1
  • 13
  • 44
  • 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. – Chris O Apr 16 '19 at 13:15
  • @ChrisO I did! No luck though. I am wondering if I missed linking with appropriate ‘*.so’ – RC0993 Apr 16 '19 at 13:18
  • Does the example compile and link correctly for you? – Vinnie Falco Apr 19 '19 at 01: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 – RC0993 Apr 19 '19 at 04:08

2 Answers2

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.

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
  • 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. – RC0993 Apr 17 '19 at 04:33
  • Also all the `#include` are able to find the required library. – RC0993 Apr 17 '19 at 04:35
  • @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. – The Quantum Physicist Apr 17 '19 at 05:49
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));
}

RC0993
  • 898
  • 1
  • 13
  • 44