2017-06-03 18:40:28 -07:00
|
|
|
[/
|
|
|
|
|
Copyright (c) 2013-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)
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
[section:control Control Frames]
|
|
|
|
|
|
|
|
|
|
Control frames are small (less than 128 bytes) messages entirely contained
|
|
|
|
|
in an individual WebSocket frame. They may be sent at any time by either
|
|
|
|
|
peer on an established connection, and can appear in between continuation
|
|
|
|
|
frames for a message. There are three types of control frames: ping, pong,
|
|
|
|
|
and close.
|
|
|
|
|
|
|
|
|
|
A sent ping indicates a request that the sender wants to receive a pong. A
|
|
|
|
|
pong is a response to a ping. Pongs may be sent unsolicited, at any time.
|
|
|
|
|
One use for an unsolicited pong is to inform the remote peer that the
|
|
|
|
|
session is still active after a long period of inactivity. A close frame
|
|
|
|
|
indicates that the remote peer wishes to close the WebSocket connection.
|
|
|
|
|
The connection is considered gracefully closed when each side has sent
|
|
|
|
|
and received a close frame.
|
|
|
|
|
|
|
|
|
|
During read operations, Beast automatically reads and processes control
|
|
|
|
|
frames. Pings are replied to as soon as possible with a pong, received
|
|
|
|
|
ping and pongs are delivered to the ping callback. The receipt of a close
|
|
|
|
|
frame initiates the WebSocket close procedure, eventually resulting in the
|
|
|
|
|
error code [link beast.ref.websocket__error `error::closed`] being delivered
|
|
|
|
|
to the caller in a subsequent read operation, assuming no other error
|
|
|
|
|
takes place.
|
|
|
|
|
|
|
|
|
|
A consequence of this automatic behavior is that caller-initiated read
|
|
|
|
|
operations can cause socket writes. However, these writes will not
|
|
|
|
|
compete with caller-initiated write operations. For the purposes of
|
|
|
|
|
correctness with respect to the stream invariants, caller-initiated
|
|
|
|
|
read operations still only count as a read. This means that callers can
|
|
|
|
|
have a simultaneously active read, write, and ping operation in progress,
|
|
|
|
|
while the implementation also automatically handles control frames.
|
|
|
|
|
|
|
|
|
|
[heading Ping and Pong Frames]
|
|
|
|
|
|
|
|
|
|
Ping and pong messages are control frames which may be sent at any time
|
|
|
|
|
by either peer on an established WebSocket connection. They are sent
|
|
|
|
|
using the functions
|
|
|
|
|
[link beast.ref.websocket__stream.ping `ping`] and
|
|
|
|
|
[link beast.ref.websocket__stream.pong `pong`].
|
|
|
|
|
|
|
|
|
|
To be notified of ping and pong control frames, callers may register a
|
|
|
|
|
"ping callback" using [link beast.ref.websocket__stream.set_option `set_option`].
|
|
|
|
|
The object provided with this option should be callable with the following
|
|
|
|
|
signature:
|
|
|
|
|
```
|
|
|
|
|
void on_ping(bool is_pong, websocket::ping_data const& payload);
|
|
|
|
|
...
|
|
|
|
|
ws.set_option(ping_callback{&on_ping});
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
When a ping callback is registered, all pings and pongs received through
|
|
|
|
|
either synchronous read functions or asynchronous read functions will
|
|
|
|
|
invoke the ping callback, with the value of `is_pong` set to `true` if a
|
2017-06-04 17:25:55 -07:00
|
|
|
pong was received or `false` otherwise. The payload of the ping or pong
|
|
|
|
|
control frame is passed in the payload argument.
|
2017-06-03 18:40:28 -07:00
|
|
|
|
|
|
|
|
Unlike regular completion handlers used in calls to asynchronous initiation
|
|
|
|
|
functions, the ping callback only needs to be set once. The callback is not
|
|
|
|
|
reset when a ping or pong is received. The same callback is used for both
|
|
|
|
|
synchronous and asynchronous reads. The ping callback is passive; in order
|
|
|
|
|
to receive pings and pongs, a synchronous or asynchronous stream read
|
|
|
|
|
function must be active.
|
|
|
|
|
|
|
|
|
|
[note
|
|
|
|
|
When an asynchronous read function receives a ping or pong, the
|
|
|
|
|
ping callback is invoked in the same manner as that used to invoke
|
|
|
|
|
the final completion handler of the corresponding read function.
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
[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.websocket__stream.close `close`]
|
|
|
|
|
function:
|
|
|
|
|
```
|
|
|
|
|
ws.close();
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
[important
|
|
|
|
|
To receive the
|
|
|
|
|
[link beast.ref.websocket__error `error::closed`]
|
|
|
|
|
error, a read operation is required.
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
[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:
|
|
|
|
|
```
|
|
|
|
|
...
|
|
|
|
|
ws.set_option(websocket::auto_fragment{true});
|
|
|
|
|
ws.set_option(websocket::write_buffer_size{16384});
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
[endsect]
|