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 These complete programs are intended to quickly impress upon readers
the flavor of the library. Source code and build scripts for them are 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: 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] [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: 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] [example_websocket_client]

View File

@@ -11,7 +11,7 @@
[block'''<?dbhtml stop-chunking?>'''] [block'''<?dbhtml stop-chunking?>''']
Source code and build scripts for these programs are located 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)]] [[Description] [Source File] [Source File (using SSL)]]
[ [
[HTTP, synchronous] [HTTP, synchronous]
[[example_src example/http/client/sync/http_client_sync.cpp http_client_sync.cpp]] [[path_link 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-ssl/http_client_sync_ssl.cpp http_client_sync_ssl.cpp]]
][ ][
[HTTP, asynchronous] [HTTP, asynchronous]
[[example_src example/http/client/async/http_client_async.cpp http_client_async.cpp]] [[path_link 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-ssl/http_client_async_ssl.cpp http_client_async_ssl.cpp]]
][ ][
[HTTP, coroutine] [HTTP, coroutine]
[[example_src example/http/client/coro/http_client_coro.cpp http_client_coro.cpp]] [[path_link 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-ssl/http_client_coro_ssl.cpp http_client_coro_ssl.cpp]]
][ ][
[HTTP crawl (asynchronous)] [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)]] [[Description] [Source File] [Source File (using SSL)]]
[ [
[WebSocket, synchronous] [WebSocket, synchronous]
[[example_src example/websocket/client/sync/websocket_client_sync.cpp websocket_client_sync.cpp]] [[path_link 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-ssl/websocket_client_sync_ssl.cpp websocket_client_sync_ssl.cpp]]
][ ][
[WebSocket, asynchronous] [WebSocket, asynchronous]
[[example_src example/websocket/client/async/websocket_client_async.cpp websocket_client_async.cpp]] [[path_link 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-ssl/websocket_client_async_ssl.cpp websocket_client_async_ssl.cpp]]
][ ][
[WebSocket, coroutine] [WebSocket, coroutine]
[[example_src example/websocket/client/coro/websocket_client_coro.cpp websocket_client_coro.cpp]] [[path_link 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-ssl/websocket_client_coro_ssl.cpp websocket_client_coro_ssl.cpp]]
]] ]]
[endsect] [endsect]
@@ -75,32 +75,32 @@ command line. All asynchronous servers support timeouts.
[[Description] [Source File] [Source File (using SSL)]] [[Description] [Source File] [Source File (using SSL)]]
[ [
[HTTP, synchronous] [HTTP, synchronous]
[[example_src example/http/server/sync/http_server_sync.cpp http_server_sync.cpp]] [[path_link 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-ssl/http_server_sync_ssl.cpp http_server_sync_ssl.cpp]]
][ ][
[HTTP, asynchronous] [HTTP, asynchronous]
[[example_src example/http/server/async/http_server_async.cpp http_server_async.cpp]] [[path_link 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-ssl/http_server_async_ssl.cpp http_server_async_ssl.cpp]]
][ ][
[HTTP, coroutine] [HTTP, coroutine]
[[example_src example/http/server/coro/http_server_coro.cpp http_server_coro.cpp]] [[path_link 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-ssl/http_server_coro_ssl.cpp http_server_coro_ssl.cpp]]
][ ][
[HTTP, stackless coroutine] [HTTP, stackless coroutine]
[[example_src example/http/server/stackless/http_server_stackless.cpp http_server_stackless.cpp]] [[path_link 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-ssl/http_server_stackless_ssl.cpp http_server_stackless_ssl.cpp]]
][ ][
[HTTP, fast (optimized for speed)] [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)] [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)] [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 These WebSocket servers echo back any message received, keeping the
@@ -111,23 +111,23 @@ support timeouts.
[[Description] [Source File] [Source File (using SSL)]] [[Description] [Source File] [Source File (using SSL)]]
[ [
[WebSocket, synchronous] [WebSocket, synchronous]
[[example_src example/websocket/server/sync/websocket_server_sync.cpp websocket_server_sync.cpp]] [[path_link 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-ssl/websocket_server_sync_ssl.cpp websocket_server_sync_ssl.cpp]]
][ ][
[WebSocket, asynchronous] [WebSocket, asynchronous]
[[example_src example/websocket/server/async/websocket_server_async.cpp websocket_server_async.cpp]] [[path_link 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-ssl/websocket_server_async_ssl.cpp websocket_server_async_ssl.cpp]]
][ ][
[WebSocket, coroutine] [WebSocket, coroutine]
[[example_src example/websocket/server/coro/websocket_server_coro.cpp websocket_server_coro.cpp]] [[path_link 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-ssl/websocket_server_coro_ssl.cpp websocket_server_coro_ssl.cpp]]
][ ][
[WebSocket, stackless coroutine] [WebSocket, stackless coroutine]
[[example_src example/websocket/server/stackless/websocket_server_stackless.cpp websocket_server_stackless.cpp]] [[path_link 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-ssl/websocket_server_stackless_ssl.cpp websocket_server_stackless_ssl.cpp]]
][ ][
[WebSocket, fast (suited for benchmarks)] [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] [Dual protocols: HTTP and WebSocket]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)] [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)] [Advanced, flex (plain + SSL)]
[[itemized_list [[itemized_list
@@ -162,7 +162,7 @@ and illustrate the implementation of advanced features.
[Flexible ports: plain and SSL on the same port] [Flexible ports: plain and SSL on the same port]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)] [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] [Chat Server, multi-threaded]
[[itemized_list [[itemized_list
@@ -173,7 +173,7 @@ and illustrate the implementation of advanced features.
[Dual protocols: HTTP and WebSocket] [Dual protocols: HTTP and WebSocket]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)] [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] [endsect]
@@ -203,7 +203,7 @@ in the Beast example contains improvements to the original program.
[Dual protocols: HTTP and WebSocket] [Dual protocols: HTTP and WebSocket]
[Clean exit via SIGINT (CTRL+C) or SIGTERM (kill)] [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] [Client]
[[itemized_list [[itemized_list
@@ -213,7 +213,7 @@ in the Beast example contains improvements to the original program.
[Only 60 lines total including UI] [Only 60 lines total including UI]
[Completely portable graphics] [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"] [/ "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`] [link beast.ref.boost__beast__buffered_read_stream `buffered_read_stream`]
][ ][
A timeout stream meets the requirements for synchronous and asynchronous A buffered read stream meets the requirements for synchronous and
read and write streams, and additionally implements configurable buffering asynchronous read and write streams, and additionally implements
for reads. configurable buffering for reads.
]] ]]
[[ [[
[link beast.ref.boost__beast__close_socket `close_socket`] [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 Asynchronous operations are started by calling a free function or member
function known as an asynchronous ['__async_initfn__]. This function accepts 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 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 special tokens __use_future__ and __yield_context__ for using futures
and coroutines respectively. This system of customizing the return value and coroutines respectively. This system of customizing the return value
and method of completion notification is known as the 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__async_op_base `async_op_base`]
[link beast.ref.boost__beast__stable_async_op_base `stable_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 composed asynchronous operations expressed as an intermediate
completion handler. This eliminates the need for the extensive 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. 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 stream and the completion token. The output is the error code which
is usually included in all completion handler signatures. 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] [example_core_echo_op_2]
Now that we have a declaration, we will define the body of the function. 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 in a manner equivalent to using __post__]. The function
__bind_handler__ is provided for this purpose. __bind_handler__ is provided for this purpose.
A complete, runnable version of this example may be found in the examples The listing for a complete, runnable version of this example is in
directory. [path_link example/echo-op/echo_op.cpp echo_op.cpp].
[endsect] [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 or other custom mechanism defined by the completion token. The signature
of the initiating function reflects these differences. 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: parameters, preconditions, and effects:
[example_core_detect_ssl_4] [example_core_detect_ssl_4]
@@ -103,7 +103,9 @@ callback style:
[example_core_detect_ssl_8] [example_core_detect_ssl_8]
This SSL detector is used in the advanced-flex and http-flex servers The examples
in the example directory. [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] [endsect]

View File

@@ -26,12 +26,10 @@
[template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>'''] [template indexterm1[term1] '''<indexterm><primary>'''[term1]'''</primary></indexterm>''']
[template indexterm2[term1 term2] '''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></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 include_file[path][^<'''<ulink url="../../../../'''[path]'''">'''[path]'''</ulink>'''>]]
[template issue[n] '''<ulink url="https://github.com/boostorg/beast/issues/'''[n]'''">#'''[n]'''</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 __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 __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]] [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 __AsyncReadStream__ [@boost:/doc/html/boost_asio/reference/AsyncReadStream.html ['AsyncReadStream]]]
[def __AsyncWriteStream__ [@boost:/doc/html/boost_asio/reference/AsyncWriteStream.html ['AsyncWriteStream]]] [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 __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 __ConnectCondition__ [@boost:/doc/html/boost_asio/reference/ConnectCondition.html ['ConnectCondition]]]
[def __ConnectHandler__ [@boost:/doc/html/boost_asio/reference/ConnectHandler.html ['ConnectHandler]]] [def __ConnectHandler__ [@boost:/doc/html/boost_asio/reference/ConnectHandler.html ['ConnectHandler]]]
[def __ConstBufferSequence__ [@boost:/doc/html/boost_asio/reference/ConstBufferSequence.html ['ConstBufferSequence]]] [def __ConstBufferSequence__ [@boost:/doc/html/boost_asio/reference/ConstBufferSequence.html ['ConstBufferSequence]]]

View File

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

View File

@@ -2,12 +2,14 @@
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>WebSocket Chat - CppCon2018</title> <title>Boost.Beast WebSocket Chat Client</title>
</head> </head>
<body> <body>
<h1>WebSocket Chat</h1> <h1>Boost.Beast WebSocket Chat Client</h1>
<p>Source code: <a href="https://github.com/vinniefalco/CppCon2018">https://github.com/vinniefalco/CppCon2018</a></p> <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;"> 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="connect">Connect</button>
<button class="echo-button" id="disconnect">Disconnect</button><br> <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, // improve performance). Generally this can be a security issue,
// but if your communication protocol is self-terminated (as // but if your communication protocol is self-terminated (as
// it is with both HTTP and WebSocket) then you may simply // 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 // 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. // Beast returns the error beast::http::error::partial_message.
// Therefore, if we see a short read here, it has occurred // Therefore, if we see a short read here, it has occurred
// after the message has been completed, so it is safe to ignore it. // after the message has been completed, so it is safe to ignore it.
if(ec == net::ssl::error::stream_truncated) if(ec == net::ssl::error::stream_truncated)
ec = {}; ec = {};
else if(ec) else if(ec)

View File

@@ -68,9 +68,101 @@ void set_non_blocking (Stream& stream)
template <class NextLayer> template <class NextLayer>
class counted_stream class counted_stream
{ {
NextLayer next_layer_; NextLayer next_layer_; // Reads and writes are passed through to this
std::size_t bytes_read_ = 0; std::size_t bytes_read_ = 0; // Holds the total bytes read
std::size_t bytes_written_ = 0; 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: public:
/// The type of executor used by this stream /// The type of executor used by this stream
@@ -158,32 +250,13 @@ public:
MutableBufferSequence const& buffers, MutableBufferSequence const& buffers,
ReadHandler&& handler) ReadHandler&& handler)
{ {
using handler_type = BOOST_ASIO_HANDLER_TYPE( return net::async_initiate<
ReadHandler, void(error_code, std::size_t)); ReadHandler,
struct op : async_op_base<handler_type, executor_type> void(error_code, std::size_t)>(
{ run_read_op{},
counted_stream& stream_; handler,
this,
op( buffers);
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();
} }
/// Write some data to the stream asynchronously /// Write some data to the stream asynchronously
@@ -194,35 +267,19 @@ public:
ConstBufferSequence const& buffers, ConstBufferSequence const& buffers,
WriteHandler&& handler) WriteHandler&& handler)
{ {
using handler_type = BOOST_ASIO_HANDLER_TYPE( return net::async_initiate<
WriteHandler, void(error_code, std::size_t)); WriteHandler,
struct op : async_op_base<handler_type, executor_type> void(error_code, std::size_t)>(
{ run_write_op{},
counted_stream& stream_; handler,
this,
op( counted_stream& stream, buffers);
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();
} }
}; };
//] //]
template class counted_stream<test::stream>;
BOOST_STATIC_ASSERT(is_sync_read_stream<counted_stream<test::stream>>::value); 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_sync_write_stream<counted_stream<test::stream>>::value);
BOOST_STATIC_ASSERT(is_async_read_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(&core_4_layers_snippets);
BEAST_EXPECT(&set_non_blocking<net::ip::tcp::socket>); 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>));
} }
}; };