mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 04:47:29 +02:00
@ -10,6 +10,7 @@ HTTP
|
|||||||
WebSocket
|
WebSocket
|
||||||
|
|
||||||
* Write buffer option does not change capacity
|
* Write buffer option does not change capacity
|
||||||
|
* Close connection during async_read on close frame
|
||||||
|
|
||||||
Core
|
Core
|
||||||
|
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
<member><link linkend="beast.websocket.handshaking">Handshaking</link></member>
|
<member><link linkend="beast.websocket.handshaking">Handshaking</link></member>
|
||||||
<member><link linkend="beast.websocket.messages">Messages</link></member>
|
<member><link linkend="beast.websocket.messages">Messages</link></member>
|
||||||
<member><link linkend="beast.websocket.frames">Frames</link></member>
|
<member><link linkend="beast.websocket.frames">Frames</link></member>
|
||||||
<member><link linkend="beast.websocket.controlframes">Control frames</link></member>
|
<member><link linkend="beast.websocket.control">Control Frames</link></member>
|
||||||
<member><link linkend="beast.websocket.pongs">Pong messages</link></member>
|
|
||||||
<member><link linkend="beast.websocket.buffers">Buffers</link></member>
|
<member><link linkend="beast.websocket.buffers">Buffers</link></member>
|
||||||
<member><link linkend="beast.websocket.async">Asynchronous interface</link></member>
|
<member><link linkend="beast.websocket.async">Asynchronous interface</link></member>
|
||||||
<member><link linkend="beast.websocket.io_service">The io_service</link></member>
|
<member><link linkend="beast.websocket.io_service">The io_service</link></member>
|
||||||
@ -292,42 +291,45 @@ void echo(beast::websocket::stream<boost::asio::ip::tcp::socket>& ws)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
[section:controlframes Control frames]
|
[section:control Control Frames]
|
||||||
|
|
||||||
During read operations, the implementation automatically reads and processes
|
Control frames are small (less than 128 bytes) messages entirely contained
|
||||||
WebSocket control frames such as ping, pong, and close. Pings are replied
|
in an individual WebSocket frame. They may be sent at any time by either
|
||||||
to as soon as possible, pongs are delivered to the pong callback. The receipt
|
peer on an established connection, and can appear in between continuation
|
||||||
of a close frame initiates the WebSocket close procedure, eventually resulting
|
frames for a message. There are three types of control frames: ping, pong,
|
||||||
in the error code [link beast.ref.websocket__error `error::closed`] being
|
and close.
|
||||||
delivered to the caller in a subsequent read operation, assuming no other error
|
|
||||||
|
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
|
||||||
|
pongs are delivered to the pong 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.
|
takes place.
|
||||||
|
|
||||||
To ensure timely delivery of control frames, large messages can be broken up
|
A consequence of this automatic behavior is that caller-initiated read
|
||||||
into smaller sized frames. The automatic fragment option turns on this
|
operations can cause socket writes. However, these writes will not
|
||||||
feature, and the write buffer size option determines the maximum size of
|
compete with caller-initiated write operations. For the purposes of
|
||||||
the fragments:
|
correctness with respect to the stream invariants, caller-initiated
|
||||||
```
|
read operations still only count as a read. This means that callers can
|
||||||
...
|
have a simultaneous active read and write operation in progress, while
|
||||||
ws.set_option(beast::websocket::auto_fragment{true});
|
the implementation also automatically handles control frames.
|
||||||
ws.set_option(beast::websocket::write_buffer_size{16384});
|
|
||||||
```
|
|
||||||
|
|
||||||
The WebSocket protocol defines a procedure and control message for initiating
|
[heading Ping and Pong Frames]
|
||||||
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
|
|
||||||
[link beast.ref.websocket__stream.close `close`]:
|
|
||||||
```
|
|
||||||
ws.close();
|
|
||||||
```
|
|
||||||
|
|
||||||
[note To receive the [link beast.ref.websocket__error `error::closed`]
|
Ping and pong messages are control frames which may be sent at any time
|
||||||
error, a read operation is required. ]
|
by either peer on an established WebSocket connection. They are sent
|
||||||
|
using the functions
|
||||||
[endsect]
|
[link beast.ref.websocket__stream.ping `ping`] and
|
||||||
|
[link beast.ref.websocket__stream.ping `pong`].
|
||||||
|
|
||||||
|
|
||||||
[section:pongs Pong messages]
|
|
||||||
|
|
||||||
To receive pong control frames, callers may register a "pong callback" using
|
To receive pong control frames, callers may register a "pong callback" using
|
||||||
[link beast.ref.websocket__stream.set_option `set_option`]. The object provided
|
[link beast.ref.websocket__stream.set_option `set_option`]. The object provided
|
||||||
@ -348,9 +350,47 @@ reset when a pong is received. The same callback is used for both synchronous
|
|||||||
and asynchronous reads. The pong callback is passive; in order to receive
|
and asynchronous reads. The pong callback is passive; in order to receive
|
||||||
pongs, a synchronous or asynchronous stream read function must be active.
|
pongs, a synchronous or asynchronous stream read function must be active.
|
||||||
|
|
||||||
[note When an asynchronous read function receives a pong, the the pong callback
|
[note
|
||||||
is invoked in the same manner as that used to invoke the final completion
|
When an asynchronous read function receives a pong, the the pong
|
||||||
handler of the corresponding read function.]
|
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(beast::websocket::auto_fragment{true});
|
||||||
|
ws.set_option(beast::websocket::write_buffer_size{16384});
|
||||||
|
```
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
@ -162,6 +162,7 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
|||||||
do_pong = 11,
|
do_pong = 11,
|
||||||
do_close_resume = 13,
|
do_close_resume = 13,
|
||||||
do_close = 15,
|
do_close = 15,
|
||||||
|
do_teardown = 16,
|
||||||
do_fail = 18,
|
do_fail = 18,
|
||||||
|
|
||||||
do_call_handler = 99
|
do_call_handler = 99
|
||||||
@ -379,9 +380,8 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
|||||||
d.state = do_close;
|
d.state = do_close;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// call handler;
|
d.state = do_teardown;
|
||||||
ec = error::closed;
|
break;
|
||||||
goto upcall;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
@ -454,7 +454,7 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
|||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
case do_close:
|
case do_close:
|
||||||
d.state = do_close + 1;
|
d.state = do_teardown;
|
||||||
d.ws.wr_close_ = true;
|
d.ws.wr_close_ = true;
|
||||||
BOOST_ASSERT(! d.ws.wr_block_);
|
BOOST_ASSERT(! d.ws.wr_block_);
|
||||||
d.ws.wr_block_ = &d;
|
d.ws.wr_block_ = &d;
|
||||||
@ -462,13 +462,15 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
|||||||
d.fb.data(), std::move(*this));
|
d.fb.data(), std::move(*this));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case do_close + 1:
|
//------------------------------------------------------------------
|
||||||
d.state = do_close + 2;
|
|
||||||
|
case do_teardown:
|
||||||
|
d.state = do_teardown + 1;
|
||||||
websocket_helpers::call_async_teardown(
|
websocket_helpers::call_async_teardown(
|
||||||
d.ws.next_layer(), std::move(*this));
|
d.ws.next_layer(), std::move(*this));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case do_close + 2:
|
case do_teardown + 1:
|
||||||
// call handler
|
// call handler
|
||||||
ec = error::closed;
|
ec = error::closed;
|
||||||
goto upcall;
|
goto upcall;
|
||||||
|
Reference in New Issue
Block a user