[boost] [beast] Asynchronous examples

683 views
Skip to first unread message

Phil Endecott via Boost

unread,
Jul 2, 2017, 3:08:01 PM7/2/17
to bo...@lists.boost.org, Phil Endecott
Hi,

Do any of the Beast examples show its use in asynchronous mode?

I'm wondering how difficult it is to achieve this:

future< vector< byte > > data = download(url);


Regards, Phil.






_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Vinnie Falco via Boost

unread,
Jul 2, 2017, 3:21:53 PM7/2/17
to Boost, Vinnie Falco
On Sun, Jul 2, 2017 at 12:07 PM, Phil Endecott via Boost
<bo...@lists.boost.org> wrote:
> Do any of the Beast examples show its use in asynchronous mode?

The files marked "async_*" and also multi_port.hpp use asynchronous interfaces:
https://github.com/vinniefalco/Beast/tree/78a065ba39836d91d7e70d93de7f9140f518083b/example/server-framework

The use of Beast's asynchronous HTTP interfaces is virtually identical
to Asio's.:
http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/reference/use_future_t.html

Replace `my_socket.async_read_some` with `beast::http::async_read` and
adjust parameters.

Beast uses Asio's extensible asynchronous model so however you receive
notifications when your asynchronous Asio task completes, will also
work with asynchronous HTTP function signatures. The documentation
explains some of the return value customization (its written from the
perspective
<http://vinniefalco.github.io/beast/beast/using_networking/writing_composed_operations.html>

> I'm wondering how difficult it is to achieve this:
>
> future< vector< byte > > data = download(url);

I won't candy-coat this: You're going to have to do some heavy lifting.

The `download` function is going to have to first do everything
necessary to establish the connection, using direct Asio interfaces.
If you want "https://" support you will need to write that too. In
fact, you better bring a URL parser if you want the ship to leave the
launch pad.

Once you have your socket established you'll have to fill out a
beast::http::request with the correct information and then call
beast::http::async_write to send it to the remote host. You'll need to
take care of proxy settings if any, as well as Basic Authentication if
the server requires it. If the remote host redirects you then you'll
have to handle that yourself too.

To make it work with futures, you will need to implement all of this
in the style of a "composed operation" which requires significant
boilerplate and expertise. Beast provides classes, functions,
examples, and a tutorial of this style to help you get it going:
<http://vinniefalco.github.io/beast/beast/using_networking/writing_composed_operations.html>

The signature for your initiating function will look like this:

template<class CompletionToken>
beast::async_result<
CompletionToken,
void(error_code, std::vector<char>)>
async_download(
beast::string_view url;
CompletionToken&& token);

You would call it this way:

std::future<vector<char>> result =
async_download("http://www.example.com/", boost::asio::use_future);

Hope this helps!

Thanks

Vinnie Falco via Boost

unread,
Jul 3, 2017, 9:26:36 AM7/3/17
to Boost, Vinnie Falco
On Sun, Jul 2, 2017 at 12:07 PM, Phil Endecott via Boost
<bo...@lists.boost.org> wrote:
> I'm wondering how difficult it is to achieve this:
> ...
> future< vector< byte > > data = download(url);

I should have stated more clearly that this use case is "out of scope"
for Beast (an expression getting a lot of use lately). This is an
example of higher level functionality. Specifically you're asking for
something like "C++ Requests" (i.e. Python Requests for C++). This
will be the subject of another library that I will propose, using
Beast of course.

Thanks
Reply all
Reply to author
Forward
0 new messages