Skip to content

Commit

Permalink
Add support for low latency mode
Browse files Browse the repository at this point in the history
  • Loading branch information
X-Ryl669 committed Mar 28, 2024
1 parent 5d45929 commit 986a7f8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 11 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ project(eMQTT5)
option(REDUCED_FOOTPRINT "Whether to enable reduced footprint for the client code" ON)
option(CROSSPLATFORM_SOCKET "Whether to use cross plaftform socket code (this disable SSL)" OFF)
option(ENABLE_TLS "Whether to enable TLS/SSL code (you'll need MBedTLS available)" OFF)
option(LOW_LATENCY "Whether to enable low latency code (at the cost of higher CPU usage)" OFF)

if (CROSSPLATFORM_SOCKET STREQUAL OFF AND ENABLE_TLS STREQUAL ON)
message(WARNING "As of 06/28/2020, MBedTLS is not correctly CMake compatible and does not generate a mbedtls-config.cmake file. You'll need to apply the patch from my branch found in pull request #3465")
Expand Down
3 changes: 2 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ ENDIF()
target_compile_definitions(eMQTT5 PUBLIC _DEBUG=$<CONFIG:Debug>
MinimalFootPrint=$<STREQUAL:${REDUCED_FOOTPRINT},ON>
MQTTOnlyBSDSocket=$<STREQUAL:${CROSSPLATFORM_SOCKET},OFF>
MQTTUseTLS=$<AND:$<STREQUAL:${CROSSPLATFORM_SOCKET},OFF>,$<STREQUAL:${ENABLE_TLS},ON>>)
MQTTUseTLS=$<AND:$<STREQUAL:${CROSSPLATFORM_SOCKET},OFF>,$<STREQUAL:${ENABLE_TLS},ON>>
MQTTLowLatency=$<STREQUAL:${LOW_LATENCY},ON>)

IF (WIN32)
ELSE()
Expand Down
23 changes: 22 additions & 1 deletion lib/include/Network/Clients/MQTTConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@
#define MQTTOnlyBSDSocket 1
#endif

/** Low latency mode
If set to 1, this will only wait on the receiving socket in a non blocking fashion.
You'll use this if you need to do other processing in your main application loop. It reduces latency for your
other application code at the cost of increased CPU usage since the loop time will decrease from the default
timeout set to mainly the duration of a system call.
This allow implies you provide a BSD compatible select function for the socket implementation.
Default: 0 */
#ifndef MQTTLowLatency
#define MQTTLowLatency 0
#endif

// The part below is for building only, it's made to generate a message so the configuration is visible at build time
#if _DEBUG == 1
#if MQTTUseAuth == 1
Expand Down Expand Up @@ -95,13 +108,21 @@
#define CONF_TLS "_"
#endif

#if MQTTLowLatency == 1
#define CONF_LL "LL_"
#else
#define CONF_LL "_"
#endif

#if MQTTOnlyBSDSocket == 1
#define CONF_SOCKET "BSD"
#else
#define CONF_SOCKET "CP"
#endif

#pragma message("Building eMQTT5 with flags: " CONF_AUTH CONF_UNSUB CONF_DUMP CONF_VALID CONF_TLS CONF_SOCKET)


#pragma message("Building eMQTT5 with flags: " CONF_AUTH CONF_UNSUB CONF_DUMP CONF_VALID CONF_TLS CONF_LL CONF_SOCKET)
#endif

#endif
25 changes: 16 additions & 9 deletions lib/src/Network/Clients/MQTTClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ namespace Network { namespace Client {
@retval 0 Protocol error, you should close the socket
@retval -1 Socket error
@retval -2 Timeout */
int receiveControlPacket()
int receiveControlPacket(const bool lowLatency = false)
{
if (!socket) return -1;
// Depending on the current state, we need to fetch as many bytes as possible within the given timeoutMs
Expand All @@ -192,6 +192,11 @@ namespace Network { namespace Client {
int ret = 0;
Protocol::MQTT::Common::VBInt len;

#if MQTTLowLatency == 1
// In low latency mode, return as early as possible
if (lowLatency && !socket->select(true, false, 0)) return -2;
#endif

// We want to keep track of complete timeout time over multiple operations
Time::TimeOut timeout(timeoutMs);
switch (recvState)
Expand Down Expand Up @@ -618,15 +623,12 @@ namespace Network { namespace Client {
}

// Useful socket helpers functions here
MQTTVirtual int select(bool reading, bool writing)
MQTTVirtual int select(bool reading, bool writing, bool instantaneous = false)
{
#if (_LINUX == 1)
// Linux modifies the timeout when calling select
struct timeval v = timeoutMs;
#else
// Other system don't
struct timeval & v = timeoutMs;
#endif
if (instantaneous) memset(&v, 0, sizeof(v));

fd_set set;
FD_ZERO(&set);
FD_SET(socket, &set);
Expand Down Expand Up @@ -866,7 +868,7 @@ namespace Network { namespace Client {
@retval 0 Protocol error, you should close the socket
@retval -1 Socket error
@retval -2 Timeout */
int receiveControlPacket()
int receiveControlPacket(const bool lowLatency = false)
{
if (!socket) return -1;
// Depending on the current state, we need to fetch as many bytes as possible within the given timeoutMs
Expand All @@ -883,6 +885,11 @@ namespace Network { namespace Client {
int ret = 0;
Protocol::MQTT::Common::VBInt len;

#if MQTTLowLatency == 1
// In low latency mode, return as early as possible
if (lowLatency && !socket->select(true, false, true)) return -2;
#endif

// We want to keep track of complete timeout time over multiple operations
switch (recvState)
{
Expand Down Expand Up @@ -1551,7 +1558,7 @@ namespace Network { namespace Client {
return ret;
}
// Check the server for any packet...
int ret = impl->receiveControlPacket();
int ret = impl->receiveControlPacket(true);
if (ret == 0)
{
impl->close();
Expand Down

0 comments on commit 986a7f8

Please sign in to comment.