Can someone provide a more helpful description than the docs have of the MQTT esp_mqtt_client_config_t
used in esp_mqtt_client_init()
, specifically the following 3 parameters:
struct buffer_t
size //size of MQTT send/receive buffer
out_size // size of MQTT output buffer
struct outbox_config_t
limit //Size limit for the outbox in bytes
The descriptions are vague indicate overlap in functionality.
Is the outBox
only used for holding esp_mqtt_client_enqueue()
messages and esp_mqtt_client_publish()
messages bypass the outBox
?
What is the difference between size (send/receive buffer) and out_size (output buffer) and how are they used? The terminology is confusing, is output used for send and size used for receive? Thanks
The comments in the source might be easier to follow (they provide a bit more context):
/**
* Client buffer size configuration
*
* Client have two buffers for input and output respectivelly.
*/
struct buffer_t {
int size; /* size of *MQTT* send/receive buffer*/
int out_size; /* size of *MQTT* output buffer. If not defined, defaults to the size defined by buffer_size */
} buffer; /* Buffer size configuration.*/
/**
* Client outbox configuration options.
*/
struct outbox_config_t {
uint64_t limit; /*!< Size limit for the outbox in bytes.*/
} outbox; /*!< Outbox configuration. */
outbox
(read from config here, data added here) can be used to limit the size of the outbox (if 0
then there is no limit). This limits the number of bytes used to store messages being queued/published. This is mainly for QOS1/2 messages that may need to be retransmitted if the connection drops (also used for QOS0
messages sent using esp_mqtt_client_enqueue
).
Note that the outbox
is a linked list of pointers to the message info (outbox_item_t
) and the size will change over time (this is generally checked before data is added e.g.).
esp_mqtt_client_publish() messages bypass the outBox?
Sometimes. QOS 0 messages may bypass the outbox
because they will be sent (or fail) before esp_mqtt_client_publish
returns (and, once sent, the process is complete). QOS1/2 messages do need to be stored because it may be neccessary to resend these (it's possible that the connection is lost before the message is acknowledged).
esp_mqtt_client_enqueue
does not block, so the message needs to be stored in outbox
regardless (it's sent by the background process). If you call
esp_mqtt_client_enqueue
with store=false
and qos=0
then an error will be returned (because the message would never be sent).
These are used here summarizing:
int buffer_size = config->buffer.size;
if (buffer_size <= 0) {
buffer_size = MQTT_BUFFER_SIZE_BYTE;
}
int out_buffer_size = config->buffer.out_size > 0 ? config->buffer.out_size : buffer_size;
if (mqtt_msg_buffer_init(&client->mqtt_state.connection, out_buffer_size) != ESP_OK) {...}
client->mqtt_state.in_buffer = (uint8_t *)malloc(buffer_size);
So, if out_size
is set, it's used, otherwise buffer_size
is used to set the size of connection->buffer
. This buffer is used to build outgoing MQTT packets.
in_buffer
is used when receiving data.
So, by default, the two buffers, which are used to encode/decode packets, will be the same size. However if you know that your program will receiver larger messages than it sends (or vice versa) then you can specify different sizes to optimise memory use. Note that having buffers that are too small may lead to errors because the library cannot process messages larger than the buffer.