Using Tcp timeout in beast 1.70.0

2019-05-22 19:54发布

问题:

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

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?

回答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.



回答2:

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