From cc8246e27ee086097ec0acb8f789f239c181e45f Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sun, 3 Sep 2017 18:39:15 -0700 Subject: [PATCH] Update websocket notes --- CHANGELOG.md | 2 ++ doc/qbk/06_websocket/8_notes.qbk | 29 ++++++++++++++++++++++------- test/doc/websocket_snippets.cpp | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ff0cd03..54b3e317 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ Version 112: +* Update websocket notes + API Changes: * WebSocket writes return the bytes transferred diff --git a/doc/qbk/06_websocket/8_notes.qbk b/doc/qbk/06_websocket/8_notes.qbk index 5f7e1d19..e85a0bd4 100644 --- a/doc/qbk/06_websocket/8_notes.qbk +++ b/doc/qbk/06_websocket/8_notes.qbk @@ -45,13 +45,28 @@ Like a regular __Asio__ socket, a [link beast.ref.boost__beast__websocket__stream `stream`] is not thread safe. Callers are responsible for synchronizing operations on the socket using an implicit or explicit strand, as per the Asio documentation. -The asynchronous interface supports one active read and one active write -simultaneously. Undefined behavior results if two or more reads or two or -more writes are attempted concurrently. Caller initiated WebSocket ping, pong, -and close operations each count as an active write. +The asynchronous interface supports one of each of the following operations +to be active at the same time: -The implementation uses composed asynchronous operations internally; a high -level read can cause both reads and writes to take place on the underlying -stream. This behavior is transparent to callers. +* [link beast.ref.boost__beast__websocket__stream.async_read `async_read`] or [link beast.ref.boost__beast__websocket__stream.async_read_some `async_read_some`] +* [link beast.ref.boost__beast__websocket__stream.async_write `async_write`] or [link beast.ref.boost__beast__websocket__stream.async_write_some `async_write_some`] +* [link beast.ref.boost__beast__websocket__stream.async_ping `async_ping`] or [link beast.ref.boost__beast__websocket__stream.async_pong `async_pong`] +* [link beast.ref.boost__beast__websocket__stream.async_close `async_close`] + +For example, the following code is malformed, because the program is +attempting to perform two simultaneous reads: + +[ws_snippet_24] + +However, this code is well-formed: + +[ws_snippet_25] + +The implementation uses composed asynchronous operations internally; +although some individiual operations can perform both reads and writes, +this behavior is coordinated internally to make sure the underlying stream +is operated in a safe fashion. This allows an asynchronous read operation +to respond to a received ping frame even while a user-initiated call to +asynchronous write is active. [endsect] diff --git a/test/doc/websocket_snippets.cpp b/test/doc/websocket_snippets.cpp index 5bac49af..aece3a6f 100644 --- a/test/doc/websocket_snippets.cpp +++ b/test/doc/websocket_snippets.cpp @@ -215,6 +215,25 @@ boost::asio::ip::tcp::socket sock{ios}; // Do something with the buffer }); //] + +{ + multi_buffer b; +//[ws_snippet_24 + ws.async_read(b, [](error_code, std::size_t){}); + ws.async_read(b, [](error_code, std::size_t){}); +//] +} + +{ + multi_buffer b; +//[ws_snippet_25 + ws.async_read(b, [](error_code, std::size_t){}); + ws.async_write(b.data(), [](error_code, std::size_t){}); + ws.async_ping({}, [](error_code){}); + ws.async_close({}, [](error_code){}); +//] +} + } } // fxx()