mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 21:34:46 +02:00
websocket documentation
This commit is contained in:
@@ -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:
|
||||
|
||||
|
@@ -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]
|
||||
|
@@ -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]
|
||||
|
@@ -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]
|
||||
|
@@ -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:
|
||||
|
@@ -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]
|
||||
|
||||
|
66
doc/qbk/06_websocket/7_teardown.qbk
Normal file
66
doc/qbk/06_websocket/7_teardown.qbk
Normal 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]
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user