mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37: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
|
||||
* 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:
|
||||
|
@ -561,7 +561,7 @@ public:
|
||||
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,
|
||||
or close control frame is received during a call to one
|
||||
@ -577,7 +577,11 @@ public:
|
||||
or asynchronous read function. The operation is passive,
|
||||
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
|
||||
void
|
||||
callback(
|
||||
@ -585,10 +589,9 @@ public:
|
||||
string_view payload // The payload in the frame
|
||||
);
|
||||
@endcode
|
||||
|
||||
For close frames, the close reason code may be obtained by
|
||||
calling the function @ref reason.
|
||||
|
||||
The implementation type-erases the callback without requiring
|
||||
a dynamic allocation. For this reason, the callback object is
|
||||
passed by a non-constant reference.
|
||||
If the read operation which receives the control frame is
|
||||
an asynchronous operation, the callback will be invoked using
|
||||
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.
|
||||
Attempting to send a close frame after a close frame is
|
||||
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
|
||||
control_callback(
|
||||
std::function<void(frame_type, string_view)> cb)
|
||||
control_callback()
|
||||
{
|
||||
ctrl_cb_ = std::move(cb);
|
||||
ctrl_cb_ = {};
|
||||
}
|
||||
|
||||
/** 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};
|
||||
//[ws_snippet_17
|
||||
ws.control_callback(
|
||||
auto cb =
|
||||
[](frame_type kind, string_view payload)
|
||||
{
|
||||
// Do something with the payload
|
||||
boost::ignore_unused(kind, payload);
|
||||
});
|
||||
};
|
||||
ws.control_callback(cb);
|
||||
//]
|
||||
|
||||
//[ws_snippet_18
|
||||
|
@ -1675,50 +1675,56 @@ public:
|
||||
bool once;
|
||||
|
||||
// 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
|
||||
multi_buffer db;
|
||||
c.read(ws, db);
|
||||
BEAST_EXPECT(once);
|
||||
BEAST_EXPECT(ws.got_binary());
|
||||
BEAST_EXPECT(to_string(db.data()) == "Hello");
|
||||
once = false;
|
||||
auto cb =
|
||||
[&](frame_type kind, string_view s)
|
||||
{
|
||||
BEAST_EXPECT(kind == frame_type::pong);
|
||||
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
|
||||
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
|
||||
multi_buffer db;
|
||||
c.read(ws, db);
|
||||
BEAST_EXPECT(once);
|
||||
BEAST_EXPECT(to_string(db.data()) == "Hello, World!");
|
||||
once = false;
|
||||
auto cb =
|
||||
[&](frame_type kind, string_view s)
|
||||
{
|
||||
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
|
||||
c.pong(ws, "");
|
||||
|
Reference in New Issue
Block a user