Todos os produtos
Search
Central de documentação

ApsaraMQ for RocketMQ:Código de exemplo para .NET SDK 1.x/2.x

Última atualização: Jun 27, 2026

As instâncias do ApsaraMQ for RocketMQ 5.x são compatíveis com o RocketMQ 1.x e 2.x SDK for .NET. Os exemplos a seguir mostram como enviar e receber mensagens normais, ordenadas, agendadas/atrasadas e transacionais.

Importante
  • Os SDKs mais recentes do RocketMQ 5.x oferecem total compatibilidade com brokers 5.x e incluem mais recursos. Para mais informações, consulte Release notes.

  • A Alibaba Cloud mantém os SDKs cliente do RocketMQ 3.x, 4.x e TCP apenas para cargas de trabalho existentes.

Pré-requisitos

Antes de executar o código de exemplo, prepare o ambiente. Para mais informações, consulte Prepare the environment.

Configuração comum

Todos os exemplos configuram ONSFactoryProperty com os parâmetros a seguir. Substitua os espaços reservados pelos valores reais.

Espaço reservado

Descrição

Exemplo

<your-instance-username>

Nome de usuário da instância disponível na aba Intelligent Authentication da página Access Control

--

<your-instance-password>

Senha da instância disponível na aba Intelligent Authentication da página Access Control

--

<your-group-id>

Group ID criado no console do ApsaraMQ for RocketMQ

GID_example

<your-topic>

Tópico criado no console do ApsaraMQ for RocketMQ

T_example_topic_name

<your-endpoint>

Endpoint obtido no console do ApsaraMQ for RocketMQ (apenas domínio e porta — sem prefixo http:// ou https://, sem endereço IP resolvido)

rmq-cn-XXXX.rmq.aliyuncs.com:8080

Importante
  • Use o nome de usuário e a senha da instância como AccessKey e SecretKey, não o par de AccessKey da sua conta Alibaba Cloud.

  • Não especifique o ID da instância ao acessar uma instância 5.x com o .NET SDK 1.x/2.x. Especificar o ID da instância causa falha na conexão.

  • Se o cliente for executado em uma instância ECS dentro de uma VPC, o broker obterá as credenciais automaticamente. Ignore a configuração de AccessKey e SecretKey.

  • Para instâncias serverless acessadas pela internet, sempre especifique o nome de usuário e a senha. Se você ativar a autenticação livre em VPCs para a instância serverless e se conectar de dentro de uma VPC, ignore as credenciais.

Mensagens normais

Enviar mensagens normais

using System;
using ons;

public class ProducerExampleForEx
{
    public ProducerExampleForEx()
    {
    }

    static void Main(string[] args) {
        ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
        // Instance username and password from the Intelligent Authentication tab
        // of the Access Control page in the ApsaraMQ for RocketMQ console.
        // Do not use your Alibaba Cloud account AccessKey pair.
        factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, "<your-instance-username>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, "<your-instance-password>");
        // Do not specify the instance ID for 5.x instances.

        // Group ID created in the console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.ProducerId, "<your-group-id>");
        // Topic created in the console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<your-topic>");
        // Endpoint from the console. Use domain:port only -- no http:// prefix, no resolved IP.
        factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "<your-endpoint>");
        // Log path.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.LogPath, "C://log");

        // Create a producer. Producers are thread-safe; in most cases, each thread requires only one instance.
        Producer producer = ONSFactory.getInstance().createProducer(factoryInfo);

        // Start the producer.
        producer.start();

        // Create and send messages.
        Message msg = new Message(factoryInfo.getPublishTopics(), "tagA", "Example message body");
        msg.setKey(Guid.NewGuid().ToString());
        for (int i = 0; i < 32; i++) {
            try
            {
                SendResultONS sendResult = producer.send(msg);
                Console.WriteLine("send success {0}", sendResult.getMessageId());
            }
            catch (Exception ex)
            {
                Console.WriteLine("send failure{0}", ex.ToString());
            }
        }

        // Shut down the producer before exiting the thread.
        producer.shutdown();

    }
}

Inscrever-se em mensagens normais

using System;
using System.Threading;
using System.Text;
using ons;

// Callback invoked when a message arrives from the broker.
public class MyMsgListener : MessageListener
{
    public MyMsgListener()
    {
    }

    ~MyMsgListener()
    {
    }

    public override ons.Action consume(Message value, ConsumeContext context)
    {
        Byte[] text = Encoding.Default.GetBytes(value.getBody());
        Console.WriteLine(Encoding.UTF8.GetString(text));
        return ons.Action.CommitMessage;
    }
}

public class ConsumerExampleForEx
{
    public ConsumerExampleForEx()
    {
    }

    static void Main(string[] args) {
        ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
        // Instance credentials from the Intelligent Authentication tab
        // of the Access Control page. Do not use Alibaba Cloud account keys.
        factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, "<your-instance-username>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, "<your-instance-password>");
        // Do not specify the instance ID for 5.x instances.

        // Consumer group ID created in the console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.ConsumerId, "<your-group-id>");
        // Topic created in the console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<your-topic>");
        // TCP endpoint from the Instance Details page in the console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.NAMESRV_ADDR, "<your-endpoint>");
        // Log path.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.LogPath, "C://log");
        // Consumption mode: clustering (default) or broadcasting.
        // factoryInfo.setFactoryProperty(ONSFactoryProperty:: MessageModel, ONSFactoryProperty.CLUSTERING);
        // factoryInfo.setFactoryProperty(ONSFactoryProperty:: MessageModel, ONSFactoryProperty.BROADCASTING);

        // Create a push consumer.
        PushConsumer consumer = ONSFactory.getInstance().createPushConsumer(factoryInfo);

        // Subscribe to the topic with a wildcard tag filter.
        consumer.subscribe(factoryInfo.getPublishTopics(), "*", new MyMsgListener());

        // Start the consumer.
        consumer.start();

        // Demo only. In production, keep the process running.
        Thread.Sleep(300000);

        // Shut down the consumer before exiting the process.
        consumer.shutdown();
    }
}

Mensagens ordenadas

Mensagens ordenadas garantem entrega FIFO para mensagens que compartilham a mesma chave de sharding.

Enviar mensagens ordenadas

A principal diferença em relação às mensagens normais é o uso de OrderProducer e a passagem de uma shardingKey para send(). Mensagens com a mesma chave de sharding são entregues em ordem.

using System;
using ons;

public class OrderProducerExampleForEx
{
    public OrderProducerExampleForEx()
    {
    }

    static void Main(string[] args) {
        ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
        // Instance credentials.
        factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, "<your-instance-username>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, "<your-instance-password>");
        // Do not specify the instance ID for 5.x instances.

        factoryInfo.setFactoryProperty(ONSFactoryProperty.ProducerId, "<your-group-id>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<your-topic>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "<your-endpoint>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty.LogPath, "C://log");

        // Create an order producer (not a regular Producer).
        OrderProducer producer = ONSFactory.getInstance().createOrderProducer(factoryInfo);

        producer.start();

        Message msg = new Message(factoryInfo.getPublishTopics(), "tagA", "Example message body");
        // Messages with the same sharding key are delivered in order.
        string shardingKey = "App-Test";
        for (int i = 0; i < 32; i++) {
            try
            {
                SendResultONS sendResult = producer.send(msg, shardingKey);
                Console.WriteLine("send success {0}", sendResult.getMessageId());
            }
            catch (Exception ex)
            {
                Console.WriteLine("send failure{0}", ex.ToString());
            }
        }

        producer.shutdown();

    }
}

Inscrever-se em mensagens ordenadas

Use OrderConsumer e implemente MessageOrderListener. Retorne OrderAction.Success em caso de sucesso ou OrderAction.Suspend para tentar novamente.

using System;
using System.Text;
using System.Threading;
using ons;

namespace demo
{

    public class MyMsgOrderListener : MessageOrderListener
    {
        public MyMsgOrderListener()
        {

        }

        ~MyMsgOrderListener()
        {
        }

        public override ons.OrderAction consume(Message value, ConsumeOrderContext context)
        {
            Byte[] text = Encoding.Default.GetBytes(value.getBody());
            Console.WriteLine(Encoding.UTF8.GetString(text));
            return ons.OrderAction.Success;
        }
    }

    class OrderConsumerExampleForEx
    {
        static void Main(string[] args)
        {
            ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
            // Instance credentials.
            factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, "<your-instance-username>");
            factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, "<your-instance-password>");
            // Do not specify the instance ID for 5.x instances.

            factoryInfo.setFactoryProperty(ONSFactoryProperty.ProducerId, "<your-group-id>");
            factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<your-topic>");
            factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "<your-endpoint>");
            factoryInfo.setFactoryProperty(ONSFactoryProperty.LogPath, "C://log");

            // Create an order consumer (not a regular PushConsumer).
            OrderConsumer consumer = ONSFactory.getInstance().createOrderConsumer(factoryInfo);

            consumer.subscribe(factoryInfo.getPublishTopics(), "*",new MyMsgOrderListener());

            consumer.start();

            // Demo only. In production, keep the process running.
            Thread.Sleep(30000);

            consumer.shutdown();
        }
    }
}

Mensagens agendadas e atrasadas

Mensagens agendadas e atrasadas são entregues após um timestamp especificado. Defina o horário de entrega com setStartDeliverTime().

Enviar mensagens agendadas ou atrasadas

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using ons;

namespace ons
{
    class onscsharp
    {
        static void Main(string[] args)
        {
            ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
            factoryInfo.setFactoryProperty(ONSFactoryProperty.ProducerId, "<your-group-id>");
            factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "<your-endpoint>");
            factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<your-topic>");
            factoryInfo.setFactoryProperty(ONSFactoryProperty.MsgContent, "<your-message-content>");
            // Instance credentials.
            factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, "<your-instance-username>");
            factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, "<your-instance-password>");
            // Do not specify the instance ID for 5.x instances.

            Producer pProducer = ONSFactory.getInstance().createProducer(factoryInfo);

            // Call start() once before sending messages.
            pProducer.start();

            Message msg = new Message(
                factoryInfo.getPublishTopics(),
                "TagA",
                factoryInfo.getMessageContent()
            );

            // Optional: set a business key for message tracing in the console.
            msg.setKey("ORDERID_100");

            // Set the delivery time in milliseconds. The message is delivered after this timestamp.
            // In this example, the message is delivered 3 seconds from now.
            long deliverTime = System.currentTimeMillis() + 3000;
            msg.setStartDeliverTime(deliverTime);

            try
            {
                SendResultONS sendResult = pProducer.send(msg);
            }
            catch(ONSClientException e)
            {
                // Handle the send failure.
            }

            // Shut down the producer before exiting. Skipping shutdown may cause memory leaks.
            pProducer.shutdown();

        }
 }
}

Inscrever-se em mensagens agendadas ou atrasadas

Inscreva-se em mensagens agendadas e atrasadas da mesma forma que em mensagens normais. Para mais informações, consulte Inscrever-se em mensagens normais.

Mensagens transacionais

Mensagens transacionais usam commit de duas fases: envie uma half message com um executor de transação local e confirme o status da transação com um verificador. O broker chama o verificador se não receber um commit ou rollback dentro do tempo limite.

Enviar mensagens transacionais

Etapa 1: Enviar uma half message e executar a transação local

Implemente LocalTransactionExecuter para executar a lógica de negócios após o envio da half message. Retorne CommitTransaction, RollbackTransaction ou Unknow conforme o resultado.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using ons;

namespace ons
{
public class MyLocalTransactionExecuter : LocalTransactionExecuter
{
    public MyLocalTransactionExecuter()
    {
    }

    ~MyLocalTransactionExecuter()
    {
    }
    public override TransactionStatus execute(Message value)
    {
            Console.WriteLine("execute topic: {0}, tag:{1}, key:{2}, msgId:{3},msgbody:{4}, userProperty:{5}",
            value.getTopic(), value.getTag(), value.getKey(), value.getMsgID(), value.getBody(), value.getUserProperty("VincentNoUser"));

            // Use the message ID and a CRC32/MD5 hash of the body to deduplicate messages.
            string msgId = value.getMsgID();

            TransactionStatus transactionStatus = TransactionStatus.Unknow;
            try {
                boolean isCommit = Execution result of the local transaction;
                if (isCommit) {
                    // Commit the message if the local transaction succeeds.
                    transactionStatus = TransactionStatus.CommitTransaction;
                } else {
                    // Roll back the message if the local transaction fails.
                    transactionStatus = TransactionStatus.RollbackTransaction;
                }
            } catch (Exception e) {
                // Handle the exception.
            }
            return transactionStatus;
    }
}
class onscsharp
{

    static void Main(string[] args)
    {
        ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
        factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "<your-endpoint>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<your-topic>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty.MsgContent, "<your-message-content>");
        // Instance credentials.
        factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, "<your-instance-username>");
        factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, "<your-instance-password>");
        // Do not specify the instance ID for 5.x instances.

        // Create a transaction producer with a transaction checker.
        LocalTransactionChecker myChecker = new MyLocalTransactionChecker();
        TransactionProducer pProducer =ONSFactory.getInstance().createTransactionProducer(factoryInfo,ref myChecker);

        // Call start() once. After startup, send messages concurrently from multiple threads.
        pProducer.start();

            Message msg = new Message(
            factoryInfo.getPublishTopics(),
            "TagA",
            factoryInfo.getMessageContent()
        );

        // Optional: set a business key for message tracing in the console.
        msg.setKey("ORDERID_100");

        try
        {
            LocalTransactionExecuter myExecuter = new MyLocalTransactionExecuter();
            SendResultONS sendResult = pProducer.send(msg, ref myExecuter);
        }
        catch(ONSClientException e)
        {
            Console.WriteLine("\nexception of sendmsg:{0}",e.what() );
        }

        // Shut down the producer before exiting. The producer cannot be restarted after shutdown.
        pProducer.shutdown();
    }
}
}

Etapa 2: Implementar o verificador de status da transação

O broker invoca LocalTransactionChecker.check() para verificar o status da transação quando não recebe um commit ou rollback. Implemente lógica idempotente para lidar com chamadas de verificação repetidas.

public class MyLocalTransactionChecker : LocalTransactionChecker
{
    public MyLocalTransactionChecker()
    {
    }
    ~MyLocalTransactionChecker()
    {
    }
    public override TransactionStatus check(Message value)
    {
            Console.WriteLine("check topic: {0}, tag:{1}, key:{2}, msgId:{3},msgbody:{4}, userProperty:{5}",
            value.getTopic(), value.getTag(), value.getKey(), value.getMsgID(), value.getBody(), value.getUserProperty("VincentNoUser"));
            // Use the message ID and a CRC32/MD5 hash of the body to deduplicate.
            string msgId = value.getMsgID();

            TransactionStatus transactionStatus = TransactionStatus.Unknow;
            try {
                boolean isCommit = Execution result of the local transaction;
                if (isCommit) {
                    // Commit the message if the local transaction succeeded.
                    transactionStatus = TransactionStatus.CommitTransaction;
                } else {
                    // Roll back the message if the local transaction failed.
                    transactionStatus = TransactionStatus.RollbackTransaction;
                }
            } catch (Exception e) {
                // Handle the exception.
            }
            return transactionStatus;
    }
}

Inscrever-se em mensagens transacionais

Inscreva-se em mensagens transacionais da mesma forma que em mensagens normais. Para mais informações, consulte Inscrever-se em mensagens normais.

Referências