Todos os produtos
Search
Central de documentação

ApsaraMQ for RocketMQ:Send and receive scheduled and delayed messages by using the C++ HTTP SDK

Última atualização: Jun 27, 2026

O ApsaraMQ for RocketMQ oferece suporte a dois tipos de mensagens com entrega diferida por meio do SDK cliente HTTP para C++:

  • Mensagens atrasadas: entregues após um intervalo específico contado a partir do envio. Por exemplo, com um atraso de 10 segundos, o consumidor recebe a mensagem 10 segundos após o envio.

  • Mensagens agendadas: entregues em um horário específico. Por exemplo, uma mensagem agendada para as 14h00 é entregue às 14h00.

Ambos os tipos usam a mesma API. Defina StartDeliverTime como um timestamp Unix em milissegundos que represente o horário de entrega desejado:

  • Mensagem atrasada: hora atual + duração do atraso. Exemplo: time(NULL) * 1000 + 10 * 1000 entrega a mensagem após 10 segundos.

  • Mensagem agendada: horário de entrega alvo convertido para um timestamp Unix em milissegundos.

Para obter mais informações sobre esses tipos de mensagem, consulte Mensagens agendadas e mensagens atrasadas.

Pré-requisitos

Antes de começar, verifique se você tem:

Enviar mensagens agendadas e atrasadas

O código a seguir envia quatro mensagens atrasadas, cada uma entregue 10 segundos após o envio. Para enviar uma mensagem agendada, defina StartDeliverTime com o horário de entrega alvo como um timestamp Unix em milissegundos.

Substitua os placeholders a seguir pelos valores reais:

Placeholder

Descrição

Onde encontrar

${HTTP_ENDPOINT}

Endpoint HTTP da instância

Página Instance Details > seção HTTP Endpoint no console do ApsaraMQ for RocketMQ

${TOPIC}

Nome do tópico

Console do ApsaraMQ for RocketMQ

${INSTANCE_ID}

ID da instância. Deixe em branco se a instância não tiver namespace

Página Instance Details no console do 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;
}

Consumir mensagens agendadas e atrasadas

Mensagens agendadas e atrasadas são consumidas da mesma forma que mensagens normais. O broker retém cada mensagem até o horário de entrega definido e depois a disponibiliza para consumo.

O código a seguir usa long polling para consumir mensagens. Nesse modo, se não houver mensagens disponíveis, a solicitação permanece aberta no broker durante o tempo especificado. O broker responde imediatamente assim que uma mensagem chega.

Substitua os placeholders a seguir pelos valores reais:

Placeholder

Descrição

Onde encontrar

${HTTP_ENDPOINT}

Endpoint HTTP da instância

Página Instance Details > seção HTTP Endpoint no console do ApsaraMQ for RocketMQ

${TOPIC}

Nome do tópico

Console do ApsaraMQ for RocketMQ

${GROUP_ID}

ID do grupo de consumidores

Console do ApsaraMQ for RocketMQ

${INSTANCE_ID}

ID da instância. Deixe em branco se a instância não tiver namespace

Página Instance Details no console do 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);
}

Veja também