YMJake.RocketMQ 0.1.0-preview.2

This is a prerelease version of YMJake.RocketMQ.
dotnet add package YMJake.RocketMQ --version 0.1.0-preview.2
                    
NuGet\Install-Package YMJake.RocketMQ -Version 0.1.0-preview.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="YMJake.RocketMQ" Version="0.1.0-preview.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="YMJake.RocketMQ" Version="0.1.0-preview.2" />
                    
Directory.Packages.props
<PackageReference Include="YMJake.RocketMQ" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add YMJake.RocketMQ --version 0.1.0-preview.2
                    
#r "nuget: YMJake.RocketMQ, 0.1.0-preview.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package YMJake.RocketMQ@0.1.0-preview.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=YMJake.RocketMQ&version=0.1.0-preview.2&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=YMJake.RocketMQ&version=0.1.0-preview.2&prerelease
                    
Install as a Cake Tool

YMJake.RocketMQ

NuGet License

English | 简体中文

An unofficial Apache RocketMQ client for .NET, speaking the RocketMQ 5.x gRPC proxy protocol.

It ships net8.0 and net10.0 targets and exposes typed, task-based APIs for the Producer, SimpleConsumer, PushConsumer, and the lite-topic consumers. The client half of the protocol is implemented from scratch: settings registration, the telemetry stream, queue assignment, long polling, receipt handles, message-body integrity checks, and reconnect.

Preview. The package is 0.1.0-preview.1. The public API may still change before 1.0.

Requirements

  • .NET 8 SDK or newer; the library targets net8.0 and net10.0.
  • A RocketMQ 5.x deployment with the proxy enabled (gRPC, default port 8081). The client connects to the proxy access point, not to a NameServer or Broker address.
  • Lite topics need a lite-enabled deployment; LiteSimpleConsumer additionally needs RocketMQ 5.5.1 or later, because older proxies reject LITE_SIMPLE_CONSUMER.

Install

dotnet add package YMJake.RocketMQ --prerelease

The package ID and the namespace differ; the code is imported with:

using RocketMQ.Client;

Features and status

✅ means the client implements the API. The corresponding server-side capability and configuration still apply.

Feature Status Notes
Producer with standard messages ✅ IProducer.SendAsync.
Producer with batch messages ✅ One topic per request and a single receipt; FIFO messages are not allowed; a partially failed batch throws.
Producer with FIFO messages ✅ Set Message.MessageGroup; the topic must be a FIFO topic.
Producer with timed/delay messages ✅ Set Message.DeliveryTimestamp.
Producer with priority messages ✅ Set Message.Priority; servers without priority queues ignore it.
Producer with transactional messages ✅ BeginTransaction / ITransaction.Commit / Rollback; a TransactionChecker resolves orphaned half messages.
Recalling timed messages ✅ RecallAsync with the RecallHandle of the send receipt, before delivery.
Lite producer messages ✅ Set Message.LiteTopic; LiteTopicQuotaExceededException reports an exhausted quota.
Simple consumer ✅ ReceiveAsync, AckAsync, ChangeInvisibleDurationAsync, runtime subscribe/unsubscribe.
Push consumer with concurrent listener ✅ Background long polling; WorkersPerQueue listeners consume one assigned queue concurrently.
Push consumer with FIFO listener ✅ FIFO groups consume one queue with a single worker, so each MessageGroup stays ordered.
Push retry and dead-letter handling ✅ A failed listener is redelivered after the server retry policy's backoff; after MaxAttempts the message is forwarded to the dead-letter queue.
Runtime subscriptions ✅ SubscribeAsync / Unsubscribe on push and simple consumers.
LitePushConsumer ✅ SubscribeLiteAsync / UnsubscribeLiteAsync at runtime, OffsetOption on first subscription, quota and limit tracking from the proxy.
LiteSimpleConsumer ✅ The lite subscription set plus explicit receive, ack, and invisible-duration changes.
Tag and SQL filtering ✅ FilterExpression with ExpressionType.Tag or ExpressionType.Sql92; SQL filtering needs the server's filtering configuration.
Credentials and request signing ✅ Pluggable ICredentialsProvider, StaticCredentialsProvider, ACL signature on every request.
Message-body integrity ✅ CRC32/MD5/SHA1 digest verification and GZIP/ZLIB decoding; failures surface as MessageView.IsCorrupted.
Telemetry, settings sync, and reconnect ✅ Telemetry stream, heartbeats, periodic route and settings refresh, automatic reconnect with backoff.
Typed errors ✅ Proxy status codes map to RocketMQ.Client.Exceptions types.

Intentionally not included: the classic Remoting protocol, an admin API, Microsoft dependency injection / Generic Host integration, and OpenTelemetry metrics or tracing.

Quick start

Producer

using RocketMQ.Client;

var config = new ClientConfig { Endpoints = "localhost:8081" };

// Topics are pre-warmed at create, so a topic missing on the server fails the start;
// without Topics the route is fetched on the first send.
var options = new ProducerOptions { MaxAttempts = 3 };
options.Topics.Add("TopicTest");

await using var producer = await Producer.Create(config, options);
var receipt = await producer.SendAsync(new Message("TopicTest", "hello"));

Push consumer

using System.Text;
using RocketMQ.Client;

var config = new ClientConfig { Endpoints = "localhost:8081" };

var options = new PushConsumerOptions { ConsumerGroup = "my-consumer-group" };
options.SubscriptionExpressions["TopicTest"] = FilterExpression.All;

await using var consumer = await PushConsumer.Create(config, options, view =>
{
    Console.WriteLine(Encoding.UTF8.GetString(view.Body));
    return ConsumeResult.Success;
});

Simple consumer

using RocketMQ.Client;

var config = new ClientConfig { Endpoints = "localhost:8081" };

var options = new SimpleConsumerOptions
{
    ConsumerGroup = "my-consumer-group",
    AwaitDuration = TimeSpan.FromSeconds(30),
};
options.SubscriptionExpressions["TopicTest"] = FilterExpression.All;

await using var consumer = await SimpleConsumer.Create(config, options);

while (true)
{
    var messages = await consumer.ReceiveAsync("TopicTest", 16, TimeSpan.FromSeconds(15));
    foreach (var message in messages)
    {
        await consumer.AckAsync(message);
    }
}

Lite consumers

using System.Text;
using RocketMQ.Client;

var config = new ClientConfig { Endpoints = "localhost:8081" };

// One bind topic carries all lite topics; the client subscribes it with "*" unless you do.
var options = new PushConsumerOptions { ConsumerGroup = "my-lite-group" };

await using var consumer = await LitePushConsumer.Create(config, "TopicTest", options, view =>
{
    Console.WriteLine($"{view.LiteTopic}: {Encoding.UTF8.GetString(view.Body)}");
    return ConsumeResult.Success;
});

await consumer.SubscribeLiteAsync("order-1", OffsetOption.Min);

Publish with new Message("TopicTest", "hello") { LiteTopic = "order-1" }.

Lite consumers require the server-side lite capability: the bind topic must accept lite messages (message.type=LITE), and the consumer group must be a lite group (lite.bind.topic=<bind topic>).

Credentials

var config = new ClientConfig
{
    Endpoints = "localhost:8081",
    CredentialsProvider = new StaticCredentialsProvider(accessKey, accessSecret),
};

Delivery semantics

  • Push: returning ConsumeResult.Success acks the message. Returning ConsumeResult.Failure, or throwing from the listener, leaves it unacked; the server redelivers it after the retry policy's backoff. A FIFO message is redelivered locally, keeping its receipt handle and advancing MessageView.DeliveryAttempt; after MaxAttempts it is forwarded to the dead-letter queue.
  • Simple: a received message stays invisible for the requested duration; ack it, or extend the duration with ChangeInvisibleDurationAsync before the receipt handle expires.
  • Ordering: FIFO ordering is decided by the consumer group's configuration on the server (isConsumeMessageOrderly), which the client reads during the settings handshake.

Compatibility

The gRPC push consumer is client-initiated long polling, not protocol-level Broker push. SQL filtering requires the target server's filtering configuration. This is an unofficial project and is not affiliated with or endorsed by the Apache Software Foundation.

License

Licensed under the Apache License 2.0.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0-preview.2 57 10/30/2026
0.1.0-preview.1 52 10/30/2026

ICredentialsProvider is now asynchronous
New EnvironmentVariablesCredentialsProvider reads ROCKETMQ_ACCESS_KEY and ROCKETMQ_SECRET_KEY
The README language switch points at absolute urls
The samples are one project per example