async_recv() funtion

You need to call the async_recv() function when you want to receive MQTT packets. It is similar to Boost.Asio’s async_read() function, allowing you to control packet receiving timing. async_mqtt does not use handler registering style APIs such as set_publish_handler(). If you need handler registering APIs, you can create them using async_recv().

The async_recv() function is more flexible than handler registering APIs. Additionally, it works well with the Completion Token model.

packet_variant

async_recv()'s CompletionToken parameters are error_code and packet_variant.

If there is no error, you can access the pv using the visit function and overloaded lambda expressions. Each lambda expression corresponds to the actual packet type.

packet_variant is a variant type of all MQTT packets and std::monostate. std::monostate is only used if error_conde is not success.

Note
async_mqtt has basic_foobar type and foobar type if the type contains MQTT’s Packet Identifier. basic_foobar takes a PacketIdBytes parameter. basic_foobar<2> is the same as foobar. The MQTT spec defines the size of the Packet Identifier as 2. However, some clustering brokers use an expanded Packet Identifier for inter-broker communication. General users don’t need to worry about basic_foobar types; simply use foobar.

You can access packet_variant as follows:

namespace am = async_mqtt; // always use this namespace alias in this document
// Let's say the completion token arguments are `error_code ec, packet_variant pv`.
if (ec) {
    std::cout
         << "MQTT CONNACK recv error:"
         << ec.message()
         << std::endl;
}
else {
    // `pv` can be converted to boolean. If `pv` contains a valid packet, it converts to `true`;
    // otherwise (`std::monostate`) , it converts to `false`.
    BOOST_ASSERT(pv); // if ec is not an error, then pv is always converted to true
    pv.visit(
        am::overload {
             [&](am::v3_1_1::connack_packet const& p) {
                 std::cout
                     << "MQTT CONNACK recv "
                     << "sp:" << p.session_present()
                     << std::endl;
             },
             // other packets handling code here
             [](auto const&) {}
        }
    );
}

Control Packet Type filter

You might be interested in specific packets. Your application may not need to handle non-important packets like PINGRESP, PUBACK, PUBREC, PUBREL, and PUBCOMP packets.

You can filter packets as follows:

// ep is endpoint shared_ptr
ep->async_recv(am::filter::match, {am::control_packet_type::publish}, completion_token);

When you set filter::match as the first argument, the second parameter is a list of matching MQTT Control Packet types. If unmatched packets are received, the completion_token isn’t invoked, but the received packets are appropriately processed. If an error occurs, the completion_token is invoked with a ec that contains the error.

// ep is endpoint
ep->async_recv(am::filter::except, {am::control_packet_type::pingresp, am::control_packet_type::puback}, completion_token);

When you set filter::except as the first argument, the second parameter is a list of MQTT Control Packet types to ignore. If the packets in the list are received, the completion_token isn’t invoked, but the received packets are appropriately processed. If an error occurs, the completion_token is invoked with a packet_variant that contains the error.

async_send() function

MQTT has various packet types, such as CONNECT, PUBLISH, SUBSCRIBE, and so on. To send a packet, first create the packet and then pass it as a parameter to async_send(). If the send timing is a protocol error, the async_send() CompletionToken is invoked with a system_error.

You can call async_send() continuously. The async_mqtt endpoint has a queuing mechanism. When the previous async_send() function’s CompletionToken is invoked, the next packet in the queue is sent, if it exists.

Packet Based APIs

async_mqtt automatically updates the endpoint’s internal state when sending and receiving packets. See Packet Based APIs.