From 49337d078d2064550321343734245b82d1914ca0 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Mon, 19 Jun 2017 10:24:03 +0200 Subject: [PATCH] heartbeats will now only be sent if the connection is idle --- include/connectionimpl.h | 10 +++++++++- src/connectionimpl.cpp | 21 +++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/include/connectionimpl.h b/include/connectionimpl.h index b01486f..3c805a9 100644 --- a/include/connectionimpl.h +++ b/include/connectionimpl.h @@ -123,6 +123,12 @@ protected: * @var queue */ std::queue _queue; + + /** + * Is the connection idle (meaning: a heartbeat is necessary) + * @var bool + */ + bool _idle = true; /** * Helper method to send the close frame @@ -429,9 +435,11 @@ public: /** * Send a heartbeat to keep the connection alive + * By default, this function does nothing if the connection is not in an idle state + * @param force always send the heartbeat, even if the connection is not idle * @return bool */ - bool heartbeat(); + bool heartbeat(bool force=false); /** * The actual connection is a friend and can construct this class diff --git a/src/connectionimpl.cpp b/src/connectionimpl.cpp index 4be9464..f2bd13c 100644 --- a/src/connectionimpl.cpp +++ b/src/connectionimpl.cpp @@ -268,6 +268,9 @@ void ConnectionImpl::setConnected() { // get the next message const auto &buffer = _queue.front(); + + // data is going to be sent, thus connection is not idle + _idle = false; // send it _handler->onData(_parent, buffer.data(), buffer.size()); @@ -336,6 +339,9 @@ bool ConnectionImpl::send(const Frame &frame) // are we still setting up the connection? if ((_state == state_connected && _queue.empty()) || frame.partOfHandshake()) { + // the data will be sent, so connection is not idle + _idle = false; + // we need an output buffer (this will immediately send the data) PassthroughBuffer buffer(_parent, _handler, frame); } @@ -362,6 +368,9 @@ bool ConnectionImpl::send(CopiedBuffer &&buffer) // are we waiting for other frames to be sent before us? if (_queue.empty()) { + // data will be sent, thus connection is not empty + _idle = false; + // send it directly _handler->onData(_parent, buffer.data(), buffer.size()); } @@ -377,12 +386,20 @@ bool ConnectionImpl::send(CopiedBuffer &&buffer) /** * Send a ping / heartbeat frame to keep the connection alive + * @param force also send heartbeat if connection is not idle * @return bool */ -bool ConnectionImpl::heartbeat() +bool ConnectionImpl::heartbeat(bool force) { + // do nothing if the connection is not idle (but we do reset the idle state to ensure + // that the next heartbeat will be sent if nothing is going to change from now on) + if (!force && !_idle) return _idle = true; + // send a frame - return send(HeartbeatFrame()); + if (!send(HeartbeatFrame())) return false; + + // frame has been sent, we treat the connection as idle now until some other data is sent over it + return _idle = true; } /**