websocket documentation

This commit is contained in:
Vinnie Falco
2017-08-04 18:10:18 -07:00
parent 60c8a560bf
commit 5e6ee5445e
10 changed files with 219 additions and 28 deletions

View File

@@ -15,6 +15,7 @@ WebSocket:
* Call do_fail from read_some
* eof on accept returns error::closed
* Fix stream::read_size_hint calculation
* Documentation
API Changes:

View File

@@ -35,6 +35,7 @@ Boost.Asio with a consistent asynchronous model using a modern C++ approach.
[include 06_websocket/4_server.qbk]
[include 06_websocket/5_messages.qbk]
[include 06_websocket/6_control.qbk]
[include 06_websocket/7_notes.qbk]
[include 06_websocket/7_teardown.qbk]
[include 06_websocket/8_notes.qbk]
[endsect]

View File

@@ -35,7 +35,7 @@ and `ssl::context` arguments are forwarded to the wrapped stream's constructor:
[important
Code which declares websocket stream objects using Asio SSL types
must include the file [include_file beast/websocket/ssl.hpp].
must include the file [include_file boost/beast/websocket/ssl.hpp].
]
[heading Non-owning References]

View File

@@ -13,9 +13,11 @@ A
[link beast.ref.boost__beast__websocket__stream `stream`]
automatically handles receiving and processing the HTTP response to the
handshake request. The call to handshake is successful if a HTTP response
is received with the 101 "Switching Protocols" status code. On failure,
an error is returned or an exception is thrown. Depending on the keep alive
setting, the connection may remain open for a subsequent handshake attempt.
is received with the
[@https://tools.ietf.org/html/rfc6455#section-4.2.2 ['101 Switching Protocols]]
status code. On failure, an error is returned or an exception is thrown.
Depending on the keep alive setting, the connection may remain open for
a subsequent handshake attempt.
Performing a handshake for an incoming websocket upgrade request operates
similarly. If the handshake fails, an error is returned or exception thrown:
@@ -36,8 +38,10 @@ typically look like this:
Server: Beast/40
```
][
The Sec-WebSocket-Accept field value is generated from the
request in a fashion specified by the WebSocket protocol.
The
[@https://tools.ietf.org/html/rfc6455#section-11.3.3 ['Sec-WebSocket-Accept]]
field value is generated from the request in a fashion specified by
the WebSocket protocol.
]]]
[heading Decorators]
@@ -115,4 +119,13 @@ area, and later uses those octets to attempt an HTTP WebSocket Upgrade:
[ws_snippet_14]
The implementation uses a fixed-size storage area to hold buffers passed
using these functions. If an application is reaching the limit of the
internal buffer size, then the websocket stream may be instantiated with
the next layer type of
[link beast.ref.boost__beast__buffered_read_stream `buffered_read_stream`]
to wrap the underlying stream. The buffered handshake data may be first
placed into the buffered read stream, which uses a dynamically sized
buffer.
[endsect]

View File

@@ -9,6 +9,51 @@
[section Send and Receive Messages]
Interfaces for transacting messages are structured into a couple of
layers. The highest layer provides ease of use, while lower layers provide
additional control and flexibility. The layers are arranged thusly:
[table
[[Level][Read/Write What][Description]]
[
[[*2]]
[
message
][
At the top layer, these functions allow for an entire
message to be sent or received. They are designed for
ease of use:
[link beast.ref.boost__beast__websocket__stream.read.overload2 `read`],
[link beast.ref.boost__beast__websocket__stream.write.overload2 `write`],
[link beast.ref.boost__beast__websocket__stream.async_read `async_read`], and
[link beast.ref.boost__beast__websocket__stream.async_write `async_write`].
]
][
[[*1]]
[
['partial]
][
These read functions enable partial message data to be
received into a __DynamicBuffer__. They can be configured
to perform bounded work:
[link beast.ref.boost__beast__websocket__stream.read_some.overload2 `read_some`], and
[link beast.ref.boost__beast__websocket__stream.async_read_some.overload1 `async_read_some`].
]
][
[[*0]]
[
['partial]
][
At the lowest level these read and write functions enable
partial message data to be transacted using a constant or
mutable buffer sequence:
[link beast.ref.boost__beast__websocket__stream.read_some.overload4 `read_some`],
[link beast.ref.boost__beast__websocket__stream.write_some.overload2 `write_some`],
[link beast.ref.boost__beast__websocket__stream.async_read_some.overload2 `async_read_some`], and
[link beast.ref.boost__beast__websocket__stream.async_write_some `async_write_some`].
]
]]
After the WebSocket handshake is accomplished, callers may send and receive
messages using the message oriented interface. This interface requires that
all of the buffers representing the message are known ahead of time:

View File

@@ -80,22 +80,26 @@ a stream read operation must be active.
[heading Close Frames]
The WebSocket protocol defines a procedure and control message for initiating
a close of the session. Handling of close initiated by the remote end of the
connection is performed automatically. To manually initiate a close, use
the
[link beast.ref.boost__beast__websocket__stream.close `close`] function:
The WebSocket protocol defines a procedure and control message for
initiating a close of the session. In this procedure, a host requests
the close by sending a
[@https://tools.ietf.org/html/rfc6455#section-5.5.1 ['close frame]].
To request a close use a close function such as
[link beast.ref.boost__beast__websocket__stream.close.overload2 `close`] or
[link beast.ref.boost__beast__websocket__stream.async_close `async_close`]:
[ws_snippet_18]
When the remote peer initiates a close by sending a close frame, Beast
will handle it for you by causing the next read to return `error::closed`.
When this error code is delivered, it indicates to the application that
the WebSocket connection has been closed cleanly, and that the TCP/IP
connection has been closed. After initiating a close, it is necessary to
continue reading messages until receiving the error `error::closed`. This
is because the remote peer may still be sending message and control frames
before it receives and responds to the close frame.
The close function will send a close frame, read and discard incoming
message data until receiving a close frame, and then shut down the
underlying connection before returning.
When a close frame is received by during a read operation, the implementation
will automatically respond with a close frame and then shut down the
underlying connection before returning. In this case, the read operation
will complete with the code
[link beast.ref.boost__beast__websocket__error `error::closed`].
This indicates to the caller that the connection has been closed cleanly.
[important
To receive the
@@ -105,10 +109,10 @@ before it receives and responds to the close frame.
[heading Auto-fragment]
To ensure timely delivery of control frames, large messages can be broken up
into smaller sized frames. The automatic fragment option turns on this
feature, and the write buffer size option determines the maximum size of
the fragments:
To ensure timely delivery of control frames, large outgoing messages can
be broken up into smaller sized frames. The automatic fragment option
turns on this feature, and the write buffer size option determines the
maximum size of the fragments:
[ws_snippet_19]

View File

@@ -0,0 +1,66 @@
[/
Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Official repository: https://github.com/boostorg/beast
]
[section Teardown]
The WebSocket protocol requirements described in rfc6455 section 7.1.1
outline an operation described as
[@https://tools.ietf.org/html/rfc6455#section-7.1.1 ['Close the WebSocket Connection]].
This operation cleanly discards bytes remaining at receiving endpoints
and also closes the underlying TCP/IP connection. Orderly shutdowns are
always preferred; for TLS or SSL streams, a protocol-level shutdown is
desired. This presents a small issue for the
[link beast.ref.boost__beast__websocket__stream `stream`]
implementation: the stream's `NextLayer` template type requires only
__SyncStream__ or __AsyncStream__, but those concepts do not support
the operations to shut down the connection.
To enable the implementation to perform the shutdown components of the
close operation, the library exposes two customization points expressed
as free functions associated with the next layer type:
* [link beast.ref.boost__beast__websocket__teardown `teardown`]: Overloads
of this function drain and shut down a stream synchronously.
* [link beast.ref.boost__beast__websocket__teardown `async_teardown`]:
Overloads of this function drain and shut down a stream asynchronously.
The implementation provides suitable overloads of the teardown
customization points when websocket streams are instantiated using the
Asio types __socket__ or __ssl_stream__ for the next layer. In this
case no user action is required. However, when the websocket stream is
instantiated for a user-defined type, compile errors will result if the
customization points are not provided for the user defined type.
Furthermore, user-defined types that wrap one of the Asio objects
mentioned earlier may wish to invoke a teardown customization point
for the wrapped object. This is how those tasks are accomplished.
[heading User-defined Teardown]
To provide overloads of teardown for a user-defined type, simply declare
the two free functions with the correct signature, accepting a reference
to the user-defined type as the stream parameter:
[ws_snippet_22]
When the implementation invokes the asynchronous teardown function, it
always uses an invokable completion handler. It is not necessary
to specify the return type customization when creating user-defined
overloads of `async_teardown`.
[heading Invoking Teardown]
To invoke the customization point, first bring the default implementation
into scope with a `using` statement. Then call the customization point
without namespace qualification, allowing argument-dependent lookup to
take effect:
[ws_snippet_23]
[endsect]

View File

@@ -38,12 +38,11 @@ namespace http {
fields.
The parser is optimized for the case where the input buffer
sequence consists of a single contiguous buffer. The
@ref beast::flat_buffer class is provided, which guarantees
@ref flat_buffer class is provided, which guarantees
that the input sequence of the stream buffer will be represented
by exactly one contiguous buffer. To ensure the optimum performance
of the parser, use @ref beast::flat_buffer with HTTP algorithms
such as @ref beast::http::read, @ref beast::http::read_some,
@ref beast::http::async_read, and @ref beast::http::async_read_some.
of the parser, use @ref flat_buffer with HTTP algorithms
such as @ref read, @ref read_some, @ref async_read, and @ref async_read_some.
Alternatively, the caller may use custom techniques to ensure that
the structured portion of the HTTP message (header or chunk header)
is contained in a linear buffer.

View File

@@ -232,6 +232,68 @@ void echo(stream<boost::asio::ip::tcp::socket>& ws,
//]
#endif
//[ws_snippet_22
struct custom_stream
{
friend
void
teardown(
role_type role,
custom_stream& stream,
error_code& ec);
template<class TeardownHandler>
friend
void
async_teardown(
role_type role,
custom_stream& stream,
TeardownHandler&& handler);
};
//]
//[ws_snippet_23
template<class NextLayer>
struct custom_wrapper
{
NextLayer next_layer;
template<class... Args>
explicit
custom_wrapper(Args&&... args)
: next_layer(std::forward<Args>(args)...)
{
}
friend
void
teardown(
role_type role,
custom_stream& stream,
error_code& ec)
{
using boost::beast::websocket::teardown;
teardown(role, stream.next_layer, ec);
}
template<class TeardownHandler>
friend
void
async_teardown(
role_type role,
custom_stream& stream,
TeardownHandler&& handler)
{
using boost::beast::websocket::async_teardown;
async_teardown(role, stream.next_layer, std::forward<TeardownHandler>(handler));
}
};
//]
} // doc_ws_snippets
//------------------------------------------------------------------------------