Todos los productos
Search
Centro de documentos

ApsaraMQ for RocketMQ:Envío y recepción de mensajes programados y diferidos mediante el SDK HTTP de C++

Última actualización: Sep 04, 2026

ApsaraMQ for RocketMQ admite dos tipos de mensajes con entrega diferida a través del SDK cliente HTTP para C++:

  • Mensajes diferidos: se entregan después de un retraso específico contado desde el momento del envío. Por ejemplo, con un retraso de 10 segundos, el consumidor recibe el mensaje 10 segundos después de su envío.

  • Mensajes programados: se entregan en un momento específico. Por ejemplo, un mensaje programado para las 14:00 se entrega exactamente a esa hora.

Ambos tipos usan la misma API. Establezca StartDeliverTime con una marca de tiempo Unix en milisegundos que represente la hora de entrega deseada:

  • Mensaje diferido: hora actual + duración del retraso. Ejemplo: time(NULL) * 1000 + 10 * 1000 se entrega después de 10 segundos.

  • Mensaje programado: la hora de entrega objetivo convertida a una marca de tiempo Unix en milisegundos.

Para obtener más información sobre estos tipos de mensajes, consulte Scheduled messages and delayed messages.

Requisitos previos

Antes de empezar, asegúrese de contar con lo siguiente:

Envío de mensajes programados y diferidos

El siguiente código envía cuatro mensajes diferidos; cada uno se entrega 10 segundos después del envío. Para enviar un mensaje programado, establezca StartDeliverTime con la hora de entrega objetivo como una marca de tiempo Unix en milisegundos.

Reemplace los siguientes marcadores de posición con sus valores reales:

Marcador de posición

Descripción

Dónde encontrarlo

${HTTP_ENDPOINT}

Endpoint HTTP de la instancia

Página Instance Details > sección HTTP Endpoint en la consola de ApsaraMQ for RocketMQ

${TOPIC}

Nombre del topic

Consola de ApsaraMQ for RocketMQ

${INSTANCE_ID}

ID de la instancia. Déjelo en blanco si la instancia no tiene namespace

Página Instance Details en la consola de ApsaraMQ for RocketMQ

#include <fstream>
#include <time.h>
#include "mq_http_sdk/mq_client.h"

using namespace std;
using namespace mq::http::sdk;

int main() {

    MQClient mqClient(
            // HTTP endpoint of the instance.
            "${HTTP_ENDPOINT}",
            // Make sure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID
            // and ALIBABA_CLOUD_ACCESS_KEY_SECRET are configured.
            // AccessKey ID for authentication.
            System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
            // AccessKey secret for authentication.
            System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
            );

    // Topic to send messages to. Create this topic in the ApsaraMQ for RocketMQ console.
    string topic = "${TOPIC}";
    // Instance ID. If the instance has a namespace, specify the instance ID.
    // If not, set this to an empty string.
    string instanceId = "${INSTANCE_ID}";

    MQProducerPtr producer;
    if (instanceId == "") {
        producer = mqClient.getProducerRef(topic);
    } else {
        producer = mqClient.getProducerRef(instanceId, topic);
    }

    try {
        // Send four messages in a loop.
        for (int i = 0; i < 4; i++)
        {
            PublishMessageResponse pmResp;
            // Message body.
            TopicMessage pubMsg("Hello, mq!have key!");
            // Custom message property.
            pubMsg.putProperty("a",std::to_string(i));
            // Message key.
            pubMsg.setMessageKey("MessageKey" + std::to_string(i));
            // Deliver after a 10-second delay.
            // StartDeliverTime is a millisecond-level Unix timestamp.
            // For a scheduled message, set this to the target delivery time
            // as a millisecond-level Unix timestamp.
            pubMsg.setStartDeliverTime(time(NULL) * 1000 + 10 * 1000);
            producer->publishMessage(pubMsg, pmResp);

            cout << "Publish mq message success. Topic is: " << topic
                << ", msgId is:" << pmResp.getMessageId()
                << ", bodyMD5 is:" << pmResp.getMessageBodyMD5() << endl;
        }
    } catch (MQServerException& me) {
        cout << "Request Failed: " + me.GetErrorCode() << ", requestId is:" << me.GetRequestId() << endl;
        return -1;
    } catch (MQExceptionBase& mb) {
        cout << "Request Failed: " + mb.ToString() << endl;
        return -2;
    }

    return 0;
}

Suscripción a mensajes programados y diferidos

Los mensajes programados y diferidos se consumen igual que los mensajes normales. El broker retiene cada mensaje hasta su hora de entrega y luego lo deja disponible para su consumo.

El siguiente código usa sondeo largo para consumir mensajes. En este modo, si no hay mensajes disponibles, la solicitud permanece abierta en el broker durante la duración especificada. El broker responde inmediatamente cuando llega un mensaje.

Reemplace los siguientes marcadores de posición con sus valores reales:

Marcador de posición

Descripción

Dónde encontrarlo

${HTTP_ENDPOINT}

Endpoint HTTP de la instancia

Página Instance Details > sección HTTP Endpoint en la consola de ApsaraMQ for RocketMQ

${TOPIC}

Nombre del topic

Consola de ApsaraMQ for RocketMQ

${GROUP_ID}

ID del grupo de consumidores

Consola de ApsaraMQ for RocketMQ

${INSTANCE_ID}

ID de la instancia. Déjelo en blanco si la instancia no tiene namespace

Página Instance Details en la consola de ApsaraMQ for RocketMQ

#include <vector>
#include <fstream>
#include "mq_http_sdk/mq_client.h"

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

using namespace std;
using namespace mq::http::sdk;

int main() {

    MQClient mqClient(
            // HTTP endpoint of the instance.
            "${HTTP_ENDPOINT}",
            // Make sure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID
            // and ALIBABA_CLOUD_ACCESS_KEY_SECRET are configured.
            // AccessKey ID for authentication.
            System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
            // AccessKey secret for authentication.
            System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
            );

    // Topic to consume messages from. Create this topic in the ApsaraMQ for RocketMQ console.
    string topic = "${TOPIC}";
    // Consumer group ID. Create this in the ApsaraMQ for RocketMQ console.
    string groupId = "${GROUP_ID}";
    // Instance ID. If the instance has a namespace, specify the instance ID.
    // If not, set this to an empty string.
    string instanceId = "${INSTANCE_ID}";

    MQConsumerPtr consumer;
    if (instanceId == "") {
        consumer = mqClient.getConsumerRef(topic, groupId);
    } else {
        consumer = mqClient.getConsumerRef(instanceId, topic, groupId, "");
    }

    do {
        try {
            std::vector<Message> messages;
            // Consume messages in long polling mode.
            // If no message is available, the request is held on the broker
            // for the specified duration until a message arrives.
            consumer->consumeMessage(
                    3, // Maximum messages per request (max: 16).
                    3, // Long polling timeout in seconds (max: 30).
                    messages
            );
            cout << "Consume: " << messages.size() << " Messages!" << endl;

            // Process consumed messages.
            std::vector<std::string> receiptHandles;
            for (std::vector<Message>::iterator iter = messages.begin();
                    iter != messages.end(); ++iter)
            {
                cout << "MessageId: " << iter->getMessageId()
                    << " PublishTime: " << iter->getPublishTime()
                    << " Tag: " << iter->getMessageTag()
                    << " Body: " << iter->getMessageBody()
                    << " FirstConsumeTime: " << iter->getFirstConsumeTime()
                    << " NextConsumeTime: " << iter->getNextConsumeTime()
                    << " ConsumedTimes: " << iter->getConsumedTimes()
                    << " Properties: " << iter->getPropertiesAsString()
                    << " Key: " << iter->getMessageKey() << endl;
                receiptHandles.push_back(iter->getReceiptHandle());
            }

            // ACK the consumed messages.
            // If the broker does not receive an ACK before NextConsumeTime,
            // it redelivers the message. Each consumption attempt generates
            // a new receipt handle with a unique timestamp.
            AckMessageResponse bdmResp;
            consumer->ackMessage(receiptHandles, bdmResp);
            if (!bdmResp.isSuccess()) {
                // Log failed ACKs. A timed-out receipt handle prevents
                // the broker from receiving the ACK.
                const std::vector<AckMessageFailedItem>& failedItems =
                    bdmResp.getAckMessageFailedItem();
                for (std::vector<AckMessageFailedItem>::const_iterator iter = failedItems.begin();
                        iter != failedItems.end(); ++iter)
                {
                    cout << "AckFailedItem: " << iter->errorCode
                        << "  " << iter->receiptHandle << endl;
                }
            } else {
                cout << "Ack: " << messages.size() << " messages suc!" << endl;
            }
        } catch (MQServerException& me) {
            if (me.GetErrorCode() == "MessageNotExist") {
                cout << "No message to consume! RequestId: " + me.GetRequestId() << endl;
                continue;
            }
            cout << "Request Failed: " + me.GetErrorCode() + ".RequestId: " + me.GetRequestId() << endl;
#ifdef _WIN32
            Sleep(2000);
#else
            usleep(2000 * 1000);
#endif
        } catch (MQExceptionBase& mb) {
            cout << "Request Failed: " + mb.ToString() << endl;
#ifdef _WIN32
            Sleep(2000);
#else
            usleep(2000 * 1000);
#endif
        }

    } while(true);
}

Consulte también