Skip to content

Commit

Permalink
Update websocket idle timer upon receiving a ping message
Browse files Browse the repository at this point in the history
  • Loading branch information
ashtum committed Feb 16, 2024
1 parent a6fd05c commit 83287f5
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 26 deletions.
2 changes: 2 additions & 0 deletions include/boost/beast/websocket/impl/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ class stream<NextLayer, deflateSupported>::read_some_op
// Handle ping frame
if(impl.rd_fh.op == detail::opcode::ping)
{
impl.update_timer(this->get_executor());

if(impl.ctrl_cb)
{
if(! cont)
Expand Down
33 changes: 7 additions & 26 deletions test/beast/websocket/ping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,9 @@ class ping_test : public websocket_test_suite
{
echo_server es{log};
stream<test::stream> ws{ioc_};

// We have an inactivity timeout of 2s, but don't send pings
ws.set_option(stream_base::timeout{
stream_base::none(),
std::chrono::milliseconds(2000),
std::chrono::seconds(2),
false
});
ws.next_layer().connect(es.stream());
Expand All @@ -112,28 +110,11 @@ class ping_test : public websocket_test_suite
system_error{ec});
got_timeout = true;
});
// We are connected, base state
BEAST_EXPECT(ws.impl_->idle_counter == 0);

test::run_for(ioc_, std::chrono::milliseconds(1250));
// After 1.25s idle, no timeout but idle counter is 1
BEAST_EXPECT(ws.impl_->idle_counter == 1);

test::run_for(ioc_, std::chrono::seconds(1));
es.async_ping();
test::run_for(ioc_, std::chrono::milliseconds(500));
// The server sent a ping at 1.25s mark, and we're now at 1.75s mark.
// We haven't hit the idle timer yet (happens at 1s, 2s, 3s)
BEAST_EXPECT(ws.impl_->idle_counter == 0);
BEAST_EXPECT(!got_timeout);

test::run_for(ioc_, std::chrono::milliseconds(750));
// At 2.5s total; should have triggered the idle timer
BEAST_EXPECT(ws.impl_->idle_counter == 1);
test::run_for(ioc_, std::chrono::seconds(1));
BEAST_EXPECT(!got_timeout);

test::run_for(ioc_, std::chrono::milliseconds(750));
// At 3s total; should have triggered the idle timer again without
// activity and triggered timeout.
test::run_for(ioc_, std::chrono::seconds(2));
BEAST_EXPECT(got_timeout);
}

Expand All @@ -143,7 +124,7 @@ class ping_test : public websocket_test_suite
stream<test::stream> ws{ioc_};
ws.set_option(stream_base::timeout{
stream_base::none(),
std::chrono::milliseconds(600),
std::chrono::seconds(1),
true
});
unsigned n_pongs = 0;
Expand All @@ -157,9 +138,9 @@ class ping_test : public websocket_test_suite
flat_buffer b;
ws.async_read(b, test::fail_handler(asio::error::operation_aborted));
// We are connected, base state
test::run_for(ioc_, std::chrono::seconds(1));
test::run_for(ioc_, std::chrono::seconds(2));
// About a second later, we should have close to 5 pings/pongs, and no timeout
BEAST_EXPECTS(2 <= n_pongs && n_pongs <= 3, "Unexpected nr of pings: " + std::to_string(n_pongs));
BEAST_EXPECTS(2 <= n_pongs && n_pongs <= 4, "Unexpected nr of pings: " + std::to_string(n_pongs));
}
}

Expand Down

0 comments on commit 83287f5

Please sign in to comment.