mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
websocket read returns the number of bytes inserted (API Change):
* read and async_read now return the number of bytes inserted into the caller's buffer. Actions Required: * Change the signature of completion handlers used with websocket::stream::async_read to void(error_code, std::size_t)
This commit is contained in:
@ -16,6 +16,15 @@ Version 86:
|
||||
* Fix Deferred Body Type Example Documentation
|
||||
* Add library metadata
|
||||
|
||||
API Changes:
|
||||
|
||||
* websocket read returns the number of bytes inserted
|
||||
|
||||
Actions Required:
|
||||
|
||||
* Change the signature of completion handlers used with
|
||||
websocket::stream::async_read to void(error_code, std::size_t)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 85:
|
||||
|
@ -804,7 +804,7 @@ operator()(
|
||||
|
||||
template<class NextLayer>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
std::size_t
|
||||
stream<NextLayer>::
|
||||
read(DynamicBuffer& buffer)
|
||||
{
|
||||
@ -813,14 +813,15 @@ read(DynamicBuffer& buffer)
|
||||
static_assert(beast::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
error_code ec;
|
||||
read(buffer, ec);
|
||||
auto const bytes_written = read(buffer, ec);
|
||||
if(ec)
|
||||
BOOST_THROW_EXCEPTION(system_error{ec});
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
std::size_t
|
||||
stream<NextLayer>::
|
||||
read(DynamicBuffer& buffer, error_code& ec)
|
||||
{
|
||||
@ -828,18 +829,20 @@ read(DynamicBuffer& buffer, error_code& ec)
|
||||
"SyncStream requirements not met");
|
||||
static_assert(beast::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
std::size_t bytes_written = 0;
|
||||
do
|
||||
{
|
||||
read_some(buffer, 0, ec);
|
||||
bytes_written += read_some(buffer, 0, ec);
|
||||
if(ec)
|
||||
return;
|
||||
return bytes_written;
|
||||
}
|
||||
while(! is_message_done());
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
template<class NextLayer>
|
||||
template<class DynamicBuffer, class ReadHandler>
|
||||
async_return_type<ReadHandler, void(error_code)>
|
||||
async_return_type<ReadHandler, void(error_code, std::size_t)>
|
||||
stream<NextLayer>::
|
||||
async_read(DynamicBuffer& buffer, ReadHandler&& handler)
|
||||
{
|
||||
@ -848,19 +851,15 @@ async_read(DynamicBuffer& buffer, ReadHandler&& handler)
|
||||
static_assert(beast::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer requirements not met");
|
||||
async_completion<
|
||||
ReadHandler, void(error_code)> init{handler};
|
||||
ReadHandler, void(error_code, std::size_t)> init{handler};
|
||||
read_op<
|
||||
DynamicBuffer,
|
||||
beast::detail::bound_handler<
|
||||
handler_type<ReadHandler, void(error_code)>,
|
||||
decltype(std::placeholders::_1) &> >{
|
||||
beast::bind_handler(
|
||||
handler_type<ReadHandler, void(error_code, std::size_t)> >{
|
||||
init.completion_handler,
|
||||
std::placeholders::_1),
|
||||
*this,
|
||||
buffer,
|
||||
0,
|
||||
false}();
|
||||
*this,
|
||||
buffer,
|
||||
0,
|
||||
false}();
|
||||
return init.result.get();
|
||||
}
|
||||
|
||||
|
@ -2835,43 +2835,46 @@ public:
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Read a message from the stream.
|
||||
/** Read a complete message
|
||||
|
||||
This function is used to synchronously read a message from
|
||||
the stream. The call blocks until one of the following is true:
|
||||
This function is used to synchronously read a message from the stream.
|
||||
The call blocks until one of the following is true:
|
||||
|
||||
@li A complete message is received.
|
||||
|
||||
@li A close frame is received. In this case the error indicated by
|
||||
the function will be @ref error::closed.
|
||||
|
||||
@li An error occurs on the stream.
|
||||
|
||||
This call is implemented in terms of one or more calls to the
|
||||
stream's `read_some` and `write_some` operations.
|
||||
This operation is implemented in terms of one or more calls to the next
|
||||
layer's `read_some` and `write_some` functions.
|
||||
|
||||
Upon a success, the input area of the stream buffer will
|
||||
hold the received message payload bytes (which may be zero
|
||||
in length). The functions @ref got_binary and @ref got_text
|
||||
may be used to query the stream and determine the type
|
||||
of the last received message.
|
||||
Received message data, if any, is appended to the input area of the buffer.
|
||||
The functions @ref got_binary and @ref got_text may be used to query
|
||||
the stream and determine the type of the last received message.
|
||||
|
||||
During reads, the implementation handles control frames as
|
||||
follows:
|
||||
While this operation is active, the implementation will read incoming
|
||||
control frames and handle them automatically as follows:
|
||||
|
||||
@li A pong frame is sent when a ping frame is received.
|
||||
@li The @ref control_callback will be invoked for each control frame.
|
||||
|
||||
@li The @ref control_callback is invoked when a ping frame
|
||||
or pong frame is received.
|
||||
@li For each received ping frame, a pong frame will be automatically sent.
|
||||
|
||||
@li The WebSocket close procedure is started if a close frame
|
||||
is received. In this case, the operation will eventually
|
||||
complete with the error set to @ref error::closed.
|
||||
@li If a close frame is received, the WebSocket close procedure is
|
||||
performed. In this case, when the function returns, the error
|
||||
@ref error::closed will be indicated.
|
||||
|
||||
@param buffer A dynamic buffer to hold the message data after
|
||||
any masking or decompression has been applied.
|
||||
@return The number of message payload bytes appended to the buffer.
|
||||
|
||||
@throws system_error Thrown on failure.
|
||||
@param buffer A dynamic buffer to hold the message data after any
|
||||
masking or decompression has been applied.
|
||||
|
||||
@throws system_error Thrown to indicate an error. The corresponding
|
||||
error code may be retrieved from the exception object for inspection.
|
||||
*/
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
std::size_t
|
||||
read(DynamicBuffer& buffer);
|
||||
|
||||
/** Read a message from the stream.
|
||||
@ -2910,10 +2913,10 @@ public:
|
||||
@param ec Set to indicate what error occurred, if any.
|
||||
*/
|
||||
template<class DynamicBuffer>
|
||||
void
|
||||
std::size_t
|
||||
read(DynamicBuffer& buffer, error_code& ec);
|
||||
|
||||
/** Start an asynchronous operation to read a message from the stream.
|
||||
/** Read a complete message asynchronously
|
||||
|
||||
This function is used to asynchronously read a message from
|
||||
the stream. The function call always returns immediately. The
|
||||
@ -2963,7 +2966,8 @@ public:
|
||||
function signature of the handler must be:
|
||||
@code
|
||||
void handler(
|
||||
error_code const& ec; // Result of operation
|
||||
error_code const& ec, // Result of operation
|
||||
std::size_t bytes_
|
||||
);
|
||||
@endcode
|
||||
Regardless of whether the asynchronous operation completes
|
||||
@ -2976,9 +2980,12 @@ public:
|
||||
void_or_deduced
|
||||
#else
|
||||
async_return_type<
|
||||
ReadHandler, void(error_code)>
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>
|
||||
#endif
|
||||
async_read(DynamicBuffer& buffer, ReadHandler&& handler);
|
||||
async_read(
|
||||
DynamicBuffer& buffer,
|
||||
ReadHandler&& handler);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
@ -209,7 +209,7 @@ boost::asio::ip::tcp::socket sock{ios};
|
||||
//[ws_snippet_20
|
||||
multi_buffer buffer;
|
||||
ws.async_read(buffer,
|
||||
[](error_code)
|
||||
[](error_code, std::size_t)
|
||||
{
|
||||
// Do something with the buffer
|
||||
});
|
||||
|
@ -270,7 +270,7 @@ public:
|
||||
|
||||
template<
|
||||
class NextLayer, class DynamicBuffer>
|
||||
void
|
||||
std::size_t
|
||||
read(stream<NextLayer>& ws,
|
||||
DynamicBuffer& buffer) const
|
||||
{
|
||||
@ -506,14 +506,16 @@ public:
|
||||
|
||||
template<
|
||||
class NextLayer, class DynamicBuffer>
|
||||
void
|
||||
std::size_t
|
||||
read(stream<NextLayer>& ws,
|
||||
DynamicBuffer& buffer) const
|
||||
{
|
||||
error_code ec;
|
||||
ws.async_read(buffer, yield_[ec]);
|
||||
auto const bytes_written =
|
||||
ws.async_read(buffer, yield_[ec]);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
template<
|
||||
@ -1342,7 +1344,7 @@ public:
|
||||
// Read text message with bad utf8.
|
||||
// Causes a close to be sent, blocking writes.
|
||||
ws.async_read(db,
|
||||
[&](error_code ec)
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
// Read should fail with protocol error
|
||||
++count;
|
||||
@ -1350,7 +1352,7 @@ public:
|
||||
ec == error::failed, ec.message());
|
||||
// Reads after failure are aborted
|
||||
ws.async_read(db,
|
||||
[&](error_code ec)
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
++count;
|
||||
BOOST_BEAST_EXPECTS(ec == boost::asio::
|
||||
@ -1409,7 +1411,7 @@ public:
|
||||
// Read a close frame.
|
||||
// Sends a close frame, blocking writes.
|
||||
ws.async_read(db,
|
||||
[&](error_code ec)
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
// Read should complete with error::closed
|
||||
++count;
|
||||
@ -1472,7 +1474,7 @@ public:
|
||||
multi_buffer db;
|
||||
std::size_t count = 0;
|
||||
ws.async_read(db,
|
||||
[&](error_code ec)
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
++count;
|
||||
BOOST_BEAST_EXPECTS(ec == error::closed,
|
||||
@ -1521,7 +1523,7 @@ public:
|
||||
});
|
||||
multi_buffer db;
|
||||
ws.async_read(db,
|
||||
[&](error_code ec)
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
BOOST_BEAST_EXPECTS(ec == error::closed, ec.message());
|
||||
});
|
||||
|
Reference in New Issue
Block a user