Basic api example without co-routines

47 views
Skip to first unread message

David Chappelle

unread,
Apr 13, 2015, 2:27:44 PM4/13/15
to cpp...@googlegroups.com
Can you provide some examples of how to use the non-coroutine based client. In particular how do you utilize the asynchronous handlers?

emile.co...@gmail.com

unread,
Apr 13, 2015, 3:01:55 PM4/13/15
to cpp...@googlegroups.com
On Monday, April 13, 2015 at 3:27:44 PM UTC-3, David Chappelle wrote:
Can you provide some examples of how to use the non-coroutine based client. In particular how do you utilize the asynchronous handlers?

If you're familiar with Boost.Asio, the asynchronous handlers work in essentially the same way. The major difference is that results returned via the handler parameter are wrapped in AsyncResult<T>. AsyncResult<T> is used to transport a std::error_code along with the operation's result. If you attempt to access the result when the asynchronous operation failed, it'll throw an exception. This technique is used to safeguard against users ignoring error codes and assuming that the asynchronous result is valid. The technique is also used by std::future::get.

When I get the chance, I'll expand the tutorials to show more about using the Asynchronous API (see issues #41 and #42). I also plan on providing a std::future or boost::future client API, for those who prefer to work in that fashion (issue #3) .

David Chappelle

unread,
Apr 13, 2015, 3:14:34 PM4/13/15
to cpp...@googlegroups.com
So everything is driven by the handlers?
If I want to connect a client and then join a session, how do I do this in an ordered fashion and synchronize with when the join has succeeded?
Most of what I need out of a client is synchronous behavior. i.e make a call, do something withe the result.

Emile Cormier

unread,
Apr 13, 2015, 3:34:34 PM4/13/15
to cpp...@googlegroups.com
If most of your client app consists of synchronous behavior, then I recommend that you use the coroutine-based API. This is the method shown in the chat example program, and in most of the tutorial examples. This method allows you to execute operations one after another, as if they were synchronous:

boost::asio::spawn(iosvc, [&](boost::asio::yield_context yield)
{
    auto client = CoroClient<>::create({tcpJson, tcpPack});
    client->connect(yield);
    SessionId sid = client->join("somerealm", yield);
    // etc.
});

iosvc.run();

With only the asynchronous API, you're stuck having to chain one asynchronous operation within the handler of another:

// off the top of my head, not tested
client->connect([&](AsyncResult<size_t> result)
{
    result.get(); // throws if the connect operation failed
    client->join([&](AsyncResult<SessionId> result)
    {
        auto sessionId = result.get(); // throws if the join operation failed
        // Do other stuff after joining...
    });
});

If you don't like nesting lambda function handlers within lambda function handlers, you can use the technique I show in the Async API tutorial page, near the bottom where it says:

The following example shows how to call member functions within asynchronous handlers, and how to chain one asynchronous operation after another:

Alternatively, you can wait until I implement the future-based API, and use continuations to chain one async operation after another.

Hope this helps.
Reply all
Reply to author
Forward
0 new messages