From fe74d0707215320a23ed10f989e87437c4f7ea4d Mon Sep 17 00:00:00 2001 From: Oskari Timperi Date: Tue, 16 Jan 2018 17:52:25 +0200 Subject: Fix keepalive handling Previously the code would send pings only when SocketSelect() would timeout. This was not working when a client was subscribed to a topic and would receive periodic messages but wouldn't itself send anything. This meant that SocketSelect() wouldn't timeout at any point and we wouldn't execute the check for sending a PINGREQ. The fix is to do the check for last sent packet before calling SocketSelect() so that if we haven't been sending anything for a while, we really send the PINGREQ. Fixes #10 --- src/client.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/client.c b/src/client.c index b95c8d5..51e86d9 100644 --- a/src/client.c +++ b/src/client.c @@ -374,7 +374,20 @@ int MqttClientRunOnce(MqttClient *client, int timeout) if (SIMPLEQ_EMPTY(&client->sendQueue)) { + int64_t elapsed; + LOG_DEBUG("nothing to write"); + + // If there's nothing to write at this point and we haven't sent + // any packets in keepalive seconds, we should send a ping. + + elapsed = MqttGetCurrentTime() - client->lastPacketSentTime; + if (client->keepAlive > 0 && elapsed >= client->keepAlive*1000) + { + MqttClientQueueSimplePacket(client, MqttPacketTypePingReq); + client->pingSent = 1; + events |= EV_WRITE; + } } else { @@ -462,15 +475,6 @@ int MqttClientRunOnce(MqttClient *client, int timeout) client->pingSent = 0; client->stopped = 1; } - else if (SIMPLEQ_EMPTY(&client->sendQueue)) - { - int64_t elapsed = MqttGetCurrentTime() - client->lastPacketSentTime; - if (elapsed/1000 >= client->keepAlive && client->keepAlive > 0) - { - MqttClientQueueSimplePacket(client, MqttPacketTypePingReq); - client->pingSent = 1; - } - } } if (client->stopped) -- cgit v1.2.3