heartbeats will now only be sent if the connection is idle

This commit is contained in:
Emiel Bruijntjes 2017-06-19 10:24:03 +02:00
parent fda26f20f4
commit 49337d078d
2 changed files with 28 additions and 3 deletions

View File

@ -123,6 +123,12 @@ protected:
* @var queue * @var queue
*/ */
std::queue<CopiedBuffer> _queue; std::queue<CopiedBuffer> _queue;
/**
* Is the connection idle (meaning: a heartbeat is necessary)
* @var bool
*/
bool _idle = true;
/** /**
* Helper method to send the close frame * Helper method to send the close frame
@ -429,9 +435,11 @@ public:
/** /**
* Send a heartbeat to keep the connection alive * 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 * @return bool
*/ */
bool heartbeat(); bool heartbeat(bool force=false);
/** /**
* The actual connection is a friend and can construct this class * The actual connection is a friend and can construct this class

View File

@ -268,6 +268,9 @@ void ConnectionImpl::setConnected()
{ {
// get the next message // get the next message
const auto &buffer = _queue.front(); const auto &buffer = _queue.front();
// data is going to be sent, thus connection is not idle
_idle = false;
// send it // send it
_handler->onData(_parent, buffer.data(), buffer.size()); _handler->onData(_parent, buffer.data(), buffer.size());
@ -336,6 +339,9 @@ bool ConnectionImpl::send(const Frame &frame)
// are we still setting up the connection? // are we still setting up the connection?
if ((_state == state_connected && _queue.empty()) || frame.partOfHandshake()) 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) // we need an output buffer (this will immediately send the data)
PassthroughBuffer buffer(_parent, _handler, frame); 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? // are we waiting for other frames to be sent before us?
if (_queue.empty()) if (_queue.empty())
{ {
// data will be sent, thus connection is not empty
_idle = false;
// send it directly // send it directly
_handler->onData(_parent, buffer.data(), buffer.size()); _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 * Send a ping / heartbeat frame to keep the connection alive
* @param force also send heartbeat if connection is not idle
* @return bool * @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 // 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;
} }
/** /**