mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 12:57:31 +02:00
control frame callbacks are non-const references:
fix #653 Actions Required: * Modify calls to set the control frame callback, to pass non-const reference instances, and manage the lifetime of the instance.
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@ -20,6 +20,16 @@ WebSocket:
|
|||||||
* Refactor accept, handshake ops
|
* Refactor accept, handshake ops
|
||||||
* Use read buffer instead of buffered stream
|
* Use read buffer instead of buffered stream
|
||||||
|
|
||||||
|
API Changes
|
||||||
|
|
||||||
|
* control frame callbacks are non-const references
|
||||||
|
|
||||||
|
Actions Required:
|
||||||
|
|
||||||
|
* Modify calls to set the control frame callback, to
|
||||||
|
pass non-const reference instances, and manage the
|
||||||
|
lifetime of the instance.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 90:
|
Version 90:
|
||||||
|
@ -561,7 +561,7 @@ public:
|
|||||||
return wr_opcode_ == detail::opcode::binary;
|
return wr_opcode_ == detail::opcode::binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the control frame callback.
|
/** Set a callback to be invoked on each incoming control frame.
|
||||||
|
|
||||||
Sets the callback to be invoked whenever a ping, pong,
|
Sets the callback to be invoked whenever a ping, pong,
|
||||||
or close control frame is received during a call to one
|
or close control frame is received during a call to one
|
||||||
@ -577,7 +577,11 @@ public:
|
|||||||
or asynchronous read function. The operation is passive,
|
or asynchronous read function. The operation is passive,
|
||||||
with no associated error code, and triggered by reads.
|
with no associated error code, and triggered by reads.
|
||||||
|
|
||||||
The signature of the callback must be:
|
For close frames, the close reason code may be obtained by
|
||||||
|
calling the function @ref reason.
|
||||||
|
|
||||||
|
@param cb The function object to call, which must be
|
||||||
|
invocable with this equivalent signature:
|
||||||
@code
|
@code
|
||||||
void
|
void
|
||||||
callback(
|
callback(
|
||||||
@ -585,10 +589,9 @@ public:
|
|||||||
string_view payload // The payload in the frame
|
string_view payload // The payload in the frame
|
||||||
);
|
);
|
||||||
@endcode
|
@endcode
|
||||||
|
The implementation type-erases the callback without requiring
|
||||||
For close frames, the close reason code may be obtained by
|
a dynamic allocation. For this reason, the callback object is
|
||||||
calling the function @ref reason.
|
passed by a non-constant reference.
|
||||||
|
|
||||||
If the read operation which receives the control frame is
|
If the read operation which receives the control frame is
|
||||||
an asynchronous operation, the callback will be invoked using
|
an asynchronous operation, the callback will be invoked using
|
||||||
the same method as that used to invoke the final handler.
|
the same method as that used to invoke the final handler.
|
||||||
@ -597,14 +600,26 @@ public:
|
|||||||
of a close frame. The implementation does this automatically.
|
of a close frame. The implementation does this automatically.
|
||||||
Attempting to send a close frame after a close frame is
|
Attempting to send a close frame after a close frame is
|
||||||
received will result in undefined behavior.
|
received will result in undefined behavior.
|
||||||
|
*/
|
||||||
|
template<class Callback>
|
||||||
|
void
|
||||||
|
control_callback(Callback& cb)
|
||||||
|
{
|
||||||
|
// Callback may not be constant, caller is responsible for
|
||||||
|
// managing the lifetime of the callback. Copies are not made.
|
||||||
|
BOOST_STATIC_ASSERT(! std::is_const<Callback>::value);
|
||||||
|
|
||||||
@param cb The callback to set.
|
ctrl_cb_ = std::ref(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Reset the control frame callback.
|
||||||
|
|
||||||
|
This function removes any previously set control frame callback.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
control_callback(
|
control_callback()
|
||||||
std::function<void(frame_type, string_view)> cb)
|
|
||||||
{
|
{
|
||||||
ctrl_cb_ = std::move(cb);
|
ctrl_cb_ = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the maximum incoming message size option.
|
/** Set the maximum incoming message size option.
|
||||||
|
@ -189,12 +189,13 @@ boost::asio::ip::tcp::socket sock{ios};
|
|||||||
{
|
{
|
||||||
stream<boost::asio::ip::tcp::socket> ws{ios};
|
stream<boost::asio::ip::tcp::socket> ws{ios};
|
||||||
//[ws_snippet_17
|
//[ws_snippet_17
|
||||||
ws.control_callback(
|
auto cb =
|
||||||
[](frame_type kind, string_view payload)
|
[](frame_type kind, string_view payload)
|
||||||
{
|
{
|
||||||
// Do something with the payload
|
// Do something with the payload
|
||||||
boost::ignore_unused(kind, payload);
|
boost::ignore_unused(kind, payload);
|
||||||
});
|
};
|
||||||
|
ws.control_callback(cb);
|
||||||
//]
|
//]
|
||||||
|
|
||||||
//[ws_snippet_18
|
//[ws_snippet_18
|
||||||
|
@ -1675,50 +1675,56 @@ public:
|
|||||||
bool once;
|
bool once;
|
||||||
|
|
||||||
// send ping and message
|
// send ping and message
|
||||||
once = false;
|
|
||||||
ws.control_callback(
|
|
||||||
[&](frame_type kind, string_view s)
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(kind == frame_type::pong);
|
|
||||||
BEAST_EXPECT(! once);
|
|
||||||
once = true;
|
|
||||||
BEAST_EXPECT(s == "");
|
|
||||||
});
|
|
||||||
c.ping(ws, "");
|
|
||||||
ws.binary(true);
|
|
||||||
c.write(ws, sbuf("Hello"));
|
|
||||||
{
|
{
|
||||||
// receive echoed message
|
once = false;
|
||||||
multi_buffer db;
|
auto cb =
|
||||||
c.read(ws, db);
|
[&](frame_type kind, string_view s)
|
||||||
BEAST_EXPECT(once);
|
{
|
||||||
BEAST_EXPECT(ws.got_binary());
|
BEAST_EXPECT(kind == frame_type::pong);
|
||||||
BEAST_EXPECT(to_string(db.data()) == "Hello");
|
BEAST_EXPECT(! once);
|
||||||
|
once = true;
|
||||||
|
BEAST_EXPECT(s == "");
|
||||||
|
};
|
||||||
|
ws.control_callback(cb);
|
||||||
|
c.ping(ws, "");
|
||||||
|
ws.binary(true);
|
||||||
|
c.write(ws, sbuf("Hello"));
|
||||||
|
{
|
||||||
|
// receive echoed message
|
||||||
|
multi_buffer db;
|
||||||
|
c.read(ws, db);
|
||||||
|
BEAST_EXPECT(once);
|
||||||
|
BEAST_EXPECT(ws.got_binary());
|
||||||
|
BEAST_EXPECT(to_string(db.data()) == "Hello");
|
||||||
|
}
|
||||||
|
ws.control_callback();
|
||||||
}
|
}
|
||||||
ws.control_callback({});
|
|
||||||
|
|
||||||
// send ping and fragmented message
|
// send ping and fragmented message
|
||||||
once = false;
|
|
||||||
ws.control_callback(
|
|
||||||
[&](frame_type kind, string_view s)
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(kind == frame_type::pong);
|
|
||||||
BEAST_EXPECT(! once);
|
|
||||||
once = true;
|
|
||||||
BEAST_EXPECT(s == "payload");
|
|
||||||
});
|
|
||||||
ws.ping("payload");
|
|
||||||
c.write_some(ws, false, sbuf("Hello, "));
|
|
||||||
c.write_some(ws, false, sbuf(""));
|
|
||||||
c.write_some(ws, true, sbuf("World!"));
|
|
||||||
{
|
{
|
||||||
// receive echoed message
|
once = false;
|
||||||
multi_buffer db;
|
auto cb =
|
||||||
c.read(ws, db);
|
[&](frame_type kind, string_view s)
|
||||||
BEAST_EXPECT(once);
|
{
|
||||||
BEAST_EXPECT(to_string(db.data()) == "Hello, World!");
|
BEAST_EXPECT(kind == frame_type::pong);
|
||||||
|
BEAST_EXPECT(! once);
|
||||||
|
once = true;
|
||||||
|
BEAST_EXPECT(s == "payload");
|
||||||
|
};
|
||||||
|
ws.control_callback(cb);
|
||||||
|
ws.ping("payload");
|
||||||
|
c.write_some(ws, false, sbuf("Hello, "));
|
||||||
|
c.write_some(ws, false, sbuf(""));
|
||||||
|
c.write_some(ws, true, sbuf("World!"));
|
||||||
|
{
|
||||||
|
// receive echoed message
|
||||||
|
multi_buffer db;
|
||||||
|
c.read(ws, db);
|
||||||
|
BEAST_EXPECT(once);
|
||||||
|
BEAST_EXPECT(to_string(db.data()) == "Hello, World!");
|
||||||
|
}
|
||||||
|
ws.control_callback();
|
||||||
}
|
}
|
||||||
ws.control_callback({});
|
|
||||||
|
|
||||||
// send pong
|
// send pong
|
||||||
c.pong(ws, "");
|
c.pong(ws, "");
|
||||||
|
Reference in New Issue
Block a user