This commit is contained in:
Vinnie Falco
2019-02-25 07:45:30 -08:00
parent 28eecefaaa
commit 5dd01155e6
11 changed files with 218 additions and 189 deletions

View File

@@ -12,7 +12,7 @@
These complete programs are intended to quickly impress upon readers
the flavor of the library. Source code and build scripts for them are
located in the [source_file example] directory.
located in the [path_link example example] directory.
@@ -20,7 +20,7 @@ located in the [source_file example] directory.
Use HTTP to make a GET request to a website and print the response:
File: [source_file example/http/client/sync/http_client_sync.cpp]
File: [path_link example/http/client/sync/http_client_sync.cpp http_sync_client.cpp]
[example_http_client]
@@ -32,7 +32,7 @@ File: [source_file example/http/client/sync/http_client_sync.cpp]
Establish a WebSocket connection, send a message and receive the reply:
File: [source_file example/websocket/client/sync/websocket_client_sync.cpp]
File: [path_link example/websocket/client/sync/websocket_client_sync.cpp websocket_sync_client.cpp]
[example_websocket_client]

View File

@@ -11,7 +11,7 @@
[block'''<?dbhtml stop-chunking?>''']
Source code and build scripts for these programs are located
in the [source_file example] directory.
in the [path_link example example] directory.
[/-----------------------------------------------------------------------------]
@@ -26,19 +26,19 @@ used to evaluate robustness. All asynchronous clients support timeouts.
[[Description] [Source File] [Source File (using SSL)]]
[
[HTTP, synchronous]
[[example_src example/http/client/sync/http_client_sync.cpp http_client_sync.cpp]]
[[example_src example/http/client/sync-ssl/http_client_sync_ssl.cpp http_client_sync_ssl.cpp]]
[[path_link example/http/client/sync/http_client_sync.cpp http_client_sync.cpp]]
[[path_link example/http/client/sync-ssl/http_client_sync_ssl.cpp http_client_sync_ssl.cpp]]
][
[HTTP, asynchronous]
[[example_src example/http/client/async/http_client_async.cpp http_client_async.cpp]]
[[example_src example/http/client/async-ssl/http_client_async_ssl.cpp http_client_async_ssl.cpp]]
[[path_link example/http/client/async/http_client_async.cpp http_client_async.cpp]]
[[path_link example/http/client/async-ssl/http_client_async_ssl.cpp http_client_async_ssl.cpp]]
][
[HTTP, coroutine]
[[example_src example/http/client/coro/http_client_coro.cpp http_client_coro.cpp]]
[[example_src example/http/client/coro-ssl/http_client_coro_ssl.cpp http_client_coro_ssl.cpp]]
[[path_link example/http/client/coro/http_client_coro.cpp http_client_coro.cpp]]
[[path_link example/http/client/coro-ssl/http_client_coro_ssl.cpp http_client_coro_ssl.cpp]]
][
[HTTP crawl (asynchronous)]
[[example_src example/http/client/crawl/http_crawl.cpp http_crawl.cpp]]
[[path_link example/http/client/crawl/http_crawl.cpp http_crawl.cpp]]
[]
]]
@@ -50,16 +50,16 @@ before disconnecting. All asynchronous clients support timeouts.
[[Description] [Source File] [Source File (using SSL)]]
[
[WebSocket, synchronous]
[[example_src example/websocket/client/sync/websocket_client_sync.cpp websocket_client_sync.cpp]]
[[example_src example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp websocket_client_sync_ssl.cpp]]
[[path_link example/websocket/client/sync/websocket_client_sync.cpp websocket_client_sync.cpp]]
[[path_link example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp websocket_client_sync_ssl.cpp]]
][
[WebSocket, asynchronous]
[[example_src example/websocket/client/async/websocket_client_async.cpp websocket_client_async.cpp]]
[[example_src example/websocket/client/async-ssl/websocket_client_async_ssl.cpp websocket_client_async_ssl.cpp]]
[[path_link example/websocket/client/async/websocket_client_async.cpp websocket_client_async.cpp]]
[[path_link example/websocket/client/async-ssl/websocket_client_async_ssl.cpp websocket_client_async_ssl.cpp]]
][
[WebSocket, coroutine]
[[example_src example/websocket/client/coro/websocket_client_coro.cpp websocket_client_coro.cpp]]
[[example_src example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp websocket_client_coro_ssl.cpp]]
[[path_link example/websocket/client/coro/websocket_client_coro.cpp websocket_client_coro.cpp]]
[[path_link example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp websocket_client_coro_ssl.cpp]]
]]
[endsect]
@@ -75,32 +75,32 @@ command line. All asynchronous servers support timeouts.
[[Description] [Source File] [Source File (using SSL)]]
[
[HTTP, synchronous]
[[example_src example/http/server/sync/http_server_sync.cpp http_server_sync.cpp]]
[[example_src example/http/server/sync-ssl/http_server_sync_ssl.cpp http_server_sync_ssl.cpp]]
[[path_link example/http/server/sync/http_server_sync.cpp http_server_sync.cpp]]
[[path_link example/http/server/sync-ssl/http_server_sync_ssl.cpp http_server_sync_ssl.cpp]]
][
[HTTP, asynchronous]
[[example_src example/http/server/async/http_server_async.cpp http_server_async.cpp]]
[[example_src example/http/server/async-ssl/http_server_async_ssl.cpp http_server_async_ssl.cpp]]
[[path_link example/http/server/async/http_server_async.cpp http_server_async.cpp]]
[[path_link example/http/server/async-ssl/http_server_async_ssl.cpp http_server_async_ssl.cpp]]
][
[HTTP, coroutine]
[[example_src example/http/server/coro/http_server_coro.cpp http_server_coro.cpp]]
[[example_src example/http/server/coro-ssl/http_server_coro_ssl.cpp http_server_coro_ssl.cpp]]
[[path_link example/http/server/coro/http_server_coro.cpp http_server_coro.cpp]]
[[path_link example/http/server/coro-ssl/http_server_coro_ssl.cpp http_server_coro_ssl.cpp]]
][
[HTTP, stackless coroutine]
[[example_src example/http/server/stackless/http_server_stackless.cpp http_server_stackless.cpp]]
[[example_src example/http/server/stackless-ssl/http_server_stackless_ssl.cpp http_server_stackless_ssl.cpp]]
[[path_link example/http/server/stackless/http_server_stackless.cpp http_server_stackless.cpp]]
[[path_link example/http/server/stackless-ssl/http_server_stackless_ssl.cpp http_server_stackless_ssl.cpp]]
][
[HTTP, fast (optimized for speed)]
[[example_src example/http/server/fast/http_server_fast.cpp http_server_fast.cpp]]
[[path_link example/http/server/fast/http_server_fast.cpp http_server_fast.cpp]]
[]
][
[HTTP, small (optimized for space)]
[[example_src example/http/server/small/http_server_small.cpp http_server_small.cpp]]
[[path_link example/http/server/small/http_server_small.cpp http_server_small.cpp]]
[]
][
[HTTP, flex (plain + SSL)]
[]
[[example_src example/http/server/flex/http_server_flex.cpp http_server_flex.cpp]]
[[path_link example/http/server/flex/http_server_flex.cpp http_server_flex.cpp]]
]]
These WebSocket servers echo back any message received, keeping the
@@ -111,23 +111,23 @@ support timeouts.
[[Description] [Source File] [Source File (using SSL)]]
[
[WebSocket, synchronous]
[[example_src example/websocket/server/sync/websocket_server_sync.cpp websocket_server_sync.cpp]]
[[example_src example/websocket/server/sync-ssl/websocket_server_sync_ssl.cpp websocket_server_sync_ssl.cpp]]
[[path_link example/websocket/server/sync/websocket_server_sync.cpp websocket_server_sync.cpp]]
[[path_link example/websocket/server/sync-ssl/websocket_server_sync_ssl.cpp websocket_server_sync_ssl.cpp]]
][
[WebSocket, asynchronous]
[[example_src example/websocket/server/async/websocket_server_async.cpp websocket_server_async.cpp]]
[[example_src example/websocket/server/async-ssl/websocket_server_async_ssl.cpp websocket_server_async_ssl.cpp]]
[[path_link example/websocket/server/async/websocket_server_async.cpp websocket_server_async.cpp]]
[[path_link example/websocket/server/async-ssl/websocket_server_async_ssl.cpp websocket_server_async_ssl.cpp]]
][
[WebSocket, coroutine]
[[example_src example/websocket/server/coro/websocket_server_coro.cpp websocket_server_coro.cpp]]
[[example_src example/websocket/server/coro-ssl/websocket_server_coro_ssl.cpp websocket_server_coro_ssl.cpp]]
[[path_link example/websocket/server/coro/websocket_server_coro.cpp websocket_server_coro.cpp]]
[[path_link example/websocket/server/coro-ssl/websocket_server_coro_ssl.cpp websocket_server_coro_ssl.cpp]]
][
[WebSocket, stackless coroutine]
[[example_src example/websocket/server/stackless/websocket_server_stackless.cpp websocket_server_stackless.cpp]]
[[example_src example/websocket/server/stackless-ssl/websocket_server_stackless_ssl.cpp websocket_server_stackless_ssl.cpp]]
[[path_link example/websocket/server/stackless/websocket_server_stackless.cpp websocket_server_stackless.cpp]]
[[path_link example/websocket/server/stackless-ssl/websocket_server_stackless_ssl.cpp websocket_server_stackless_ssl.cpp]]
][
[WebSocket, fast (suited for benchmarks)]
[[example_src example/websocket/server/fast/websocket_server_fast.cpp websocket_server_fast.cpp]]
[[path_link example/websocket/server/fast/websocket_server_fast.cpp websocket_server_fast.cpp]]
[]
]]
@@ -151,7 +151,7 @@ and illustrate the implementation of advanced features.
[Dual protocols: HTTP and WebSocket]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)]
]]
[[example_src example/advanced/server/advanced_server.cpp advanced_server.cpp]]
[[path_link example/advanced/server/advanced_server.cpp advanced_server.cpp]]
][
[Advanced, flex (plain + SSL)]
[[itemized_list
@@ -162,7 +162,7 @@ and illustrate the implementation of advanced features.
[Flexible ports: plain and SSL on the same port]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)]
]]
[[example_src example/advanced/server-flex/advanced_server_flex.cpp advanced_server_flex.cpp]]
[[path_link example/advanced/server-flex/advanced_server_flex.cpp advanced_server_flex.cpp]]
][
[Chat Server, multi-threaded]
[[itemized_list
@@ -173,7 +173,7 @@ and illustrate the implementation of advanced features.
[Dual protocols: HTTP and WebSocket]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)]
]]
[[source_file example/websocket/server/chat-multi]]
[[path_link example/websocket/server/chat-mult chat-multi]]
]]
[endsect]
@@ -203,7 +203,7 @@ in the Beast example contains improvements to the original program.
[Dual protocols: HTTP and WebSocket]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)]
]]
[[source_file example/websocket/server/chat-multi]]
[[path_link example/websocket/server/chat-multi chat-multi]]
][
[Client]
[[itemized_list
@@ -213,7 +213,7 @@ in the Beast example contains improvements to the original program.
[Only 60 lines total including UI]
[Completely portable graphics]
]]
[[source_file example/websocket/server/chat-multi/chat_client.html]]
[[path_link example/websocket/server/chat-multi/chat_client.html chat_client.html]]
]]
[/ "Get rich quick! Using Boost.Beast WebSockets and Networking TS"]

View File

@@ -59,9 +59,9 @@ facilities for authoring and working with layered streams:
[[
[link beast.ref.boost__beast__buffered_read_stream `buffered_read_stream`]
][
A timeout stream meets the requirements for synchronous and asynchronous
read and write streams, and additionally implements configurable buffering
for reads.
A buffered read stream meets the requirements for synchronous and
asynchronous read and write streams, and additionally implements
configurable buffering for reads.
]]
[[
[link beast.ref.boost__beast__close_socket `close_socket`]

View File

@@ -11,9 +11,9 @@
Asynchronous operations are started by calling a free function or member
function known as an asynchronous ['__async_initfn__]. This function accepts
parameters specific to the operation as well as a "completion token." The
parameters specific to the operation as well as a __CompletionToken__. The
token is either a completion handler, or a type defining how the caller is
informed of the asynchronous operation result. __Asio__ comes with the
informed of the asynchronous operation result. Networking provides the
special tokens __use_future__ and __yield_context__ for using futures
and coroutines respectively. This system of customizing the return value
and method of completion notification is known as the
@@ -47,10 +47,10 @@ composed operations:
[link beast.ref.boost__beast__async_op_base `async_op_base`]
[link beast.ref.boost__beast__stable_async_op_base `stable_async_op_base`]
][
This class is designed to be used as a base class when authoriing
This class is designed to be used as a base class when authoring
composed asynchronous operations expressed as an intermediate
completion handler. This eliminates the need for the extensive
boilerplate to propgate the associated executor, associated
boilerplate to propagate the associated executor, associated
allocator, and legacy completion handler hooks.
]]
[[

View File

@@ -17,10 +17,6 @@ initiation function. For our echo operation the only inputs are the
stream and the completion token. The output is the error code which
is usually included in all completion handler signatures.
[tip
The source for for this example is [source_file example/echo-op/echo_op.cpp].
]
[example_core_echo_op_2]
Now that we have a declaration, we will define the body of the function.
@@ -78,7 +74,7 @@ composed operations:
in a manner equivalent to using __post__]. The function
__bind_handler__ is provided for this purpose.
A complete, runnable version of this example may be found in the examples
directory.
The listing for a complete, runnable version of this example is in
[path_link example/echo-op/echo_op.cpp echo_op.cpp].
[endsect]

View File

@@ -53,7 +53,7 @@ asynchronous version delivers the error code to a completion handler
or other custom mechanism defined by the completion token. The signature
of the initiating function reflects these differences.
First we declare the initiating function and document the requirments,
First we declare the initiating function and document the requirements,
parameters, preconditions, and effects:
[example_core_detect_ssl_4]
@@ -103,7 +103,9 @@ callback style:
[example_core_detect_ssl_8]
This SSL detector is used in the advanced-flex and http-flex servers
in the example directory.
The examples
[path_link example/advanced/server/advanced_server.cpp advanced-server] and
[path_link example/advanced/server-flex/advanced_server_flex.cpp advanced-server-flex]
use this SSL detection function.
[endsect]

View File

@@ -26,12 +26,10 @@
[template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
[template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>''']
[template source_file[path] '''<ulink url="../../'''[path]'''">'''[path]'''</ulink>''']
[template path_link[path name] '''<ulink url="../../'''[path]'''">'''[name]'''</ulink>''']
[template include_file[path][^<'''<ulink url="../../../../'''[path]'''">'''[path]'''</ulink>'''>]]
[template issue[n] '''<ulink url="https://github.com/boostorg/beast/issues/'''[n]'''">#'''[n]'''</ulink>''']
[template example_src[path name] '''<ulink url="../../'''[path]'''">'''[name]'''</ulink>''']
[def __N3747__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf [*N3747]]]
[def __NetTS__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf Networking TS]]
[def __rfc6455__ [@https://tools.ietf.org/html/rfc6455 rfc6455]]
@@ -64,8 +62,9 @@
[def __AsyncReadStream__ [@boost:/doc/html/boost_asio/reference/AsyncReadStream.html ['AsyncReadStream]]]
[def __AsyncWriteStream__ [@boost:/doc/html/boost_asio/reference/AsyncWriteStream.html ['AsyncWriteStream]]]
[def __CompletionHandler__ [@boost:/doc/html/boost_asio/reference/CompletionHandler.html ['CompletionHandler]]]
[def __CompletionCondition__ [@boost:/doc/html/boost_asio/reference/CompletionCondition.html ['CompletionCondition]]]
[def __CompletionHandler__ [@boost:/doc/html/boost_asio/reference/CompletionHandler.html ['CompletionHandler]]]
[def __CompletionToken__ [@boost:/doc/html/boost_asio/reference/asynchronous_operations#boost_asio.reference.asynchronous_operations.completion_tokens_and_handlers ['CompletionToken]]]
[def __ConnectCondition__ [@boost:/doc/html/boost_asio/reference/ConnectCondition.html ['ConnectCondition]]]
[def __ConnectHandler__ [@boost:/doc/html/boost_asio/reference/ConnectHandler.html ['ConnectHandler]]]
[def __ConstBufferSequence__ [@boost:/doc/html/boost_asio/reference/ConstBufferSequence.html ['ConstBufferSequence]]]

View File

@@ -12,54 +12,51 @@
[/-----------------------------------------------------------------------------]
* [phrase library..[@/libs/beast/ Beast]:]
[role red [*BIG Update!]] The
[link beast.quickref [*reference]] shows a star [role green \u2605] next to each new item.
* [*Beast needs your help!]
* [@https://github.com/boostorg/beast/wiki/Companies-and-Individuals-Using-Beast [*Tell Us]]
how you or your company use Beast.
'''<emphasis role="bold"><emphasis role="red">BIG Update!!!</emphasis></emphasis>''' The
[@/libs/beast/doc/html/beast/quickref.html reference]
shows a star '''<emphasis role="green">&#9733;</emphasis>''' next to each new item.
* Beast needs your help!
* [@https://github.com/boostorg/beast/wiki/Companies-and-Individuals-Using-Beast Tell Us]
how you or your company use Beast
* Please
[@https://github.com/boostorg/beast/issues/new report]
any bugs, feature requests, or general feedback.
* Chat with us at the [*#beast] and [*#boost] channels in the
[@https://cppalliance.org/slack/ [*C++ Slack Workspace]].
* Don't forget to \u2b50 \u2b50 \u2b50
[@https://github.com/boostorg/beast [*star the repository]]
\u2b50 \u2b50 \u2b50 !
* [role green [*More tutorials]], code like the pros!
* [link beast.using_io.asio_refresher Networking Refresher] teaches you from the ground up.
* Updated [link beast.using_io.writing_composed_operations.echo Asynchronous Echo] example
* Updated [link beast.using_io.writing_composed_operations.detect_ssl [*Detect SSL Handshake]],
now a [link beast.ref.boost__beast__async_detect_ssl public api]!
* [@../../example/websocket/server/chat-multi websocket-chat-multi]
threaded chat server with a JavaScript browser client.
* [link beast.ref.boost__beast__basic_stream `basic_stream`] and
[link beast.ref.boost__beast__basic_stream `tcp_stream`] offer:
* Timeouts:
[link beast.ref.boost__beast__basic_stream.async_read_some `async_read_some`],
[link beast.ref.boost__beast__basic_stream.async_write_some `async_write_some`]
complete with
[link beast.ref.boost__beast__error `error::timeout`] on expiration!
any bugs, feature requests, or general feedback
* Join the [@https://cppalliance.org/slack/ [*C++ Slack Workspace]] for
free and chat with us in the #beast and #boost channels
* Don't forget to [@https://github.com/boostorg/beast star the repository] \u2b50!
* More tutorials, code like the pros!
* [@/libs/beast/doc/html/beast/using_asio/asio_refresher.html Networking Refresher]
teaches you from the ground up.
* Updated [@/libs/beast/doc/html/beast/using_io/writing_composed_operations/echo.html Asynchronous Echo] example
* Updated [@/libs/beast/doc/html/beast/using_io/writing_composed_operations/detect_ssl.html [*Detect SSL]] composed operation tutorial
* [@/libs/beast/example/websocket/server/chat-multi websocket-chat-multi]
threaded chat server with a JavaScript
[@/libs/beast/example/websocket/server/chat-multi/chat_client.html browser client]
* [@/libs/beast/doc/html/beast/ref/boost__beast__basic_stream.html `basic_stream`] and
[@/libs/beast/doc/html/beast/ref/boost__beast__tcp_stream.html `tcp_stream`] offer:
* Timeouts: `async_read_some`, `async_write_some` complete with
[@/libs/beast/doc/html/beast/ref/boost__beast__error.html `error::timeout`] on expiration!
* Traffic-shaping policies
[link beast.ref.boost__beast__simple_rate_policy `simple`] and
[link beast.ref.boost__beast__unlimited_rate_policy `unlimited`],
[@/libs/beast/doc/html/beast/ref/boost__beast__simple_rate_policy.html `simple`] and
[@/libs/beast/doc/html/beast/ref/boost__beast__unlimited_rate_policy.html `unlimited`],
or a user-defined
[link beast.concepts.RatePolicy ['RatePolicy]]!
[@/libs/beast/doc/html/beast/concepts/RatePolicy.html ['RatePolicy]]!
* Put the strand directly on the socket using
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html P1322R0],
no more `bind_executor` at call sites!
* Base classes
[link beast.ref.boost__beast__async_op_base `async_op_base`] and
[link beast.ref.boost__beast__stable_async_op_base `stable_async_op_base`]
[@/libs/beast/doc/html/beast/ref/boost__beast__async_op_base.html `async_op_base`] and
[@/libs/beast/doc/html/beast/ref/boost__beast__stable_async_op_base.html `stable_async_op_base`] and
handle all composed operation boilerplate for you.
* [link beast.ref.boost__beast__ssl_stream `ssl_stream`] provides a
* [@/libs/beast/doc/html/beast/ref/boost__beast__ssl_stream.html `ssl_stream`] provides a
movable, assignable SSL stream with a flat write optimization.
* All asynchronous operations use Asio's
[@boost:/doc/html/boost_asio/reference/async_initiate.html `async_initiate`]
for efficient integration with Coroutines TS.
* \u26a1 [*['faster compilation]], define `BOOST_BEAST_SPLIT_COMPILATION` and include
[@../../include/boost/beast/src.hpp src.hpp] in one of your .cpp files!
* See the full [link beast.release_notes [*Release Notes]] for a complete list
of changes.
* All asynchronous operations use Asio's `async_initiate` for efficient integration with Coroutines TS.
* \u26a1 [*['faster compilation]], define `BOOST_BEAST_SPLIT_COMPILATION` and
`#include <`[@/libs/beast/include/boost/beast/src.hpp `boost/beast/src.hpp`]`>`
in one of your .cpp files!
* See the full
[@/libs/beast/doc/html/beast/release_notes.html Release Notes]
for a complete list of changes.
[/-----------------------------------------------------------------------------]
@@ -304,7 +301,7 @@
* detect-ssl is rewritten
* New example [source_file example/websocket/server/chat-multi]
* New example [path_link example/websocket/server/chat-multi example/websocket/server/chat-multi]
* `async_echo` works with move-only handlers
@@ -385,7 +382,7 @@
[*Examples]
* New WebSocket server and browser-based client: [source_file example/cppcon2018]
* New WebSocket server and browser-based client: example/cppcon2018
[*Fixes]
@@ -585,8 +582,7 @@ to update to the latest Boost release.
* Fix "warning: const type qualifier on return type has no effect"
* ([issue 916]) Tidy up `ssl_stream` special members in
[source_file example/common/ssl_stream.hpp]
* ([issue 916]) Tidy up `ssl_stream` special members
* ([issue 918]) Calls to `<algorithm>` are protected from macros

View File

@@ -2,12 +2,14 @@
<html>
<head>
<meta charset="utf-8" />
<title>WebSocket Chat - CppCon2018</title>
<title>Boost.Beast WebSocket Chat Client</title>
</head>
<body>
<h1>WebSocket Chat</h1>
<p>Source code: <a href="https://github.com/vinniefalco/CppCon2018">https://github.com/vinniefalco/CppCon2018</a></p>
<h1>Boost.Beast WebSocket Chat Client</h1>
<p>
<a href="http://www.boost.org/libs/beast">Boost.Beast</a>
<a href="http://www.boost.org/libs/beast/example/websocket/server/chat-multi">Source Code</a>
</p>
Server URI: <input class="draw-border" id="uri" size="47" value="ws://localhost:8080" style="margin-bottom: 5px;">
<button class="echo-button" id="connect">Connect</button>
<button class="echo-button" id="disconnect">Disconnect</button><br>

View File

@@ -372,7 +372,7 @@ https_get (std::string const& host, std::string const& target, error_code& ec)
// improve performance). Generally this can be a security issue,
// but if your communication protocol is self-terminated (as
// it is with both HTTP and WebSocket) then you may simply
// ignore the lack of close_notify.
// ignore the lack of close_notify:
//
// https://github.com/boostorg/beast/issues/38
//
@@ -382,6 +382,7 @@ https_get (std::string const& host, std::string const& target, error_code& ec)
// Beast returns the error beast::http::error::partial_message.
// Therefore, if we see a short read here, it has occurred
// after the message has been completed, so it is safe to ignore it.
if(ec == net::ssl::error::stream_truncated)
ec = {};
else if(ec)

View File

@@ -68,9 +68,101 @@ void set_non_blocking (Stream& stream)
template <class NextLayer>
class counted_stream
{
NextLayer next_layer_;
std::size_t bytes_read_ = 0;
std::size_t bytes_written_ = 0;
NextLayer next_layer_; // Reads and writes are passed through to this
std::size_t bytes_read_ = 0; // Holds the total bytes read
std::size_t bytes_written_ = 0; // Holds the total bytes written
// This is the "initiation" object passed to async_initiate to start the operation
struct run_read_op
{
template<
class ReadHandler,
class MutableBufferSequence>
void
operator()(
ReadHandler&& handler,
counted_stream* stream,
MutableBufferSequence const& buffers)
{
using handler_type = typename std::decay<ReadHandler>::type;
// async_op_base handles all of the composed operation boilerplate for us
using base = async_op_base<
handler_type, beast::executor_type<NextLayer>>;
// Our composed operation is implemented as a completion handler object
struct op : base
{
counted_stream& stream_;
op( counted_stream& stream,
handler_type&& handler,
MutableBufferSequence const& buffers)
: base(std::move(handler), stream.get_executor())
, stream_(stream)
{
// Start the asynchronous operation
stream_.next_layer().async_read_some(buffers, std::move(*this));
}
void operator()(error_code ec, std::size_t bytes_transferred)
{
// Count the bytes transferred towards the total
stream_.bytes_read_ += bytes_transferred;
this->invoke_now(ec, bytes_transferred);
}
};
op(*stream, std::forward<ReadHandler>(handler), buffers);
}
};
// This is the "initiation" object passed to async_initiate to start the operation
struct run_write_op
{
template<
class WriteHandler,
class ConstBufferSequence>
void
operator()(
WriteHandler&& handler,
counted_stream* stream,
ConstBufferSequence const& buffers)
{
using handler_type = typename std::decay<WriteHandler>::type;
// async_op_base handles all of the composed operation boilerplate for us
using base = async_op_base<
handler_type, beast::executor_type<NextLayer>>;
// Our composed operation is implemented as a completion handler object
struct op : base
{
counted_stream& stream_;
op( counted_stream& stream,
handler_type&& handler,
ConstBufferSequence const& buffers)
: base(std::move(handler), stream.get_executor())
, stream_(stream)
{
// Start the asynchronous operation
stream_.next_layer().async_write_some(buffers, std::move(*this));
}
void operator()(error_code ec, std::size_t bytes_transferred)
{
// Count the bytes transferred towards the total
stream_.bytes_written_ += bytes_transferred;
this->invoke_now(ec, bytes_transferred);
}
};
op(*stream, std::forward<WriteHandler>(handler), buffers);
}
};
public:
/// The type of executor used by this stream
@@ -151,78 +243,43 @@ public:
}
/// Read some data from the stream asynchronously
template<class MutableBufferSequence, class ReadHandler>
template <class MutableBufferSequence, class ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void(error_code, std::size_t))
async_read_some(
MutableBufferSequence const& buffers,
ReadHandler&& handler)
{
using handler_type = BOOST_ASIO_HANDLER_TYPE(
ReadHandler, void(error_code, std::size_t));
struct op : async_op_base<handler_type, executor_type>
{
counted_stream& stream_;
op(
counted_stream& stream,
handler_type&& handler,
MutableBufferSequence const& buffers)
: async_op_base<handler_type, executor_type>(
std::move(handler), stream.get_executor())
, stream_(stream)
{
stream_.next_layer().async_read_some(buffers, std::move(*this));
}
void operator()(error_code ec, std::size_t bytes_transferred)
{
stream_.bytes_read_ += bytes_transferred;
this->invoke_now(ec, bytes_transferred);
}
};
net::async_completion<ReadHandler, void(error_code, std::size_t)> init{handler};
op(*this, std::move(init.completion_handler), buffers);
return init.result.get();
return net::async_initiate<
ReadHandler,
void(error_code, std::size_t)>(
run_read_op{},
handler,
this,
buffers);
}
/// Write some data to the stream asynchronously
template<class ConstBufferSequence, class WriteHandler>
template <class ConstBufferSequence, class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
void(error_code, std::size_t))
async_write_some(
ConstBufferSequence const& buffers,
WriteHandler&& handler)
{
using handler_type = BOOST_ASIO_HANDLER_TYPE(
WriteHandler, void(error_code, std::size_t));
struct op : async_op_base<handler_type, executor_type>
{
counted_stream& stream_;
op( counted_stream& stream,
handler_type&& handler,
ConstBufferSequence const& buffers)
: async_op_base<handler_type, executor_type>(
std::move(handler), stream.get_executor())
, stream_(stream)
{
stream_.next_layer().async_write_some(buffers, std::move(*this));
}
void operator()(error_code ec, std::size_t bytes_transferred)
{
stream_.bytes_written_ += bytes_transferred;
this->invoke_now(ec, bytes_transferred);
}
};
net::async_completion<WriteHandler, void(error_code, std::size_t)> init{handler};
op(*this, std::move(init.completion_handler), buffers);
return init.result.get();
return net::async_initiate<
WriteHandler,
void(error_code, std::size_t)>(
run_write_op{},
handler,
this,
buffers);
}
};
//]
template class counted_stream<test::stream>;
BOOST_STATIC_ASSERT(is_sync_read_stream<counted_stream<test::stream>>::value);
BOOST_STATIC_ASSERT(is_sync_write_stream<counted_stream<test::stream>>::value);
BOOST_STATIC_ASSERT(is_async_read_stream<counted_stream<test::stream>>::value);
@@ -243,30 +300,6 @@ struct core_4_layers_test
{
BEAST_EXPECT(&core_4_layers_snippets);
BEAST_EXPECT(&set_non_blocking<net::ip::tcp::socket>);
BEAST_EXPECT(&counted_stream<test::stream>::get_executor);
BEAST_EXPECT(static_cast<
test::stream&(counted_stream<test::stream>::*)()>(
&counted_stream<test::stream>::next_layer));
BEAST_EXPECT(static_cast<
test::stream const&(counted_stream<test::stream>::*)() const>(
&counted_stream<test::stream>::next_layer));
BEAST_EXPECT(&counted_stream<test::stream>::bytes_read);
BEAST_EXPECT(&counted_stream<test::stream>::bytes_written);
BEAST_EXPECT(static_cast<
std::size_t(counted_stream<test::stream>::*)(net::mutable_buffer const&)>(
&counted_stream<test::stream>::read_some));
BEAST_EXPECT(static_cast<
std::size_t(counted_stream<test::stream>::*)(net::mutable_buffer const&, error_code&)>(
&counted_stream<test::stream>::read_some));
BEAST_EXPECT(static_cast<
std::size_t(counted_stream<test::stream>::*)(net::const_buffer const&)>(
&counted_stream<test::stream>::write_some));
BEAST_EXPECT(static_cast<
std::size_t(counted_stream<test::stream>::*)(net::const_buffer const&, error_code&)>(
&counted_stream<test::stream>::write_some));
BEAST_EXPECT((&counted_stream<test::stream>::async_read_some<net::mutable_buffer, handler>));
BEAST_EXPECT((&counted_stream<test::stream>::async_write_some<net::const_buffer, handler>));
}
};