Publish/Subscribe CloudEvents in .NET, inspired by Dapr Pub/Sub Component
- Publish/Subscribe events with CloudEvent format
- With both Kafka and Redis support
- At-Least-Once delivery guarantee
- Redeliver failed events
- Obeservability support (traces/metrics)
- DOES NOT support delivery events in order
dotnet add package CloudEventDotNet
dotnet add package CloudEventDotNet.Redis # With Redis Stream
dotnet add package CloudEventDotNet.Kafka # With Apache Kafka
services.AddCloudEvents(defaultPubSubName: "kafka", defaultTopic: "my-topic")
.Load(typeof(OrderCancelled).Assembly)
.AddKafkaPubSub("kafka", options =>
{
options.ProducerConfig = new ProducerConfig
{
BootstrapServers = broker,
};
}, options =>
{
options.ConsumerConfig = new ConsumerConfig
{
BootstrapServers = broker,
GroupId = consumerGroup,
};
})
.AddRedisPubSub("redis", options =>
{
options.ConnectionMultiplexerFactory = () => redis;
options.MaxLength = maxLength;
}, options =>
{
options.ConnectionMultiplexerFactory = () => redis;
options.ConsumerGroup = consumerGroup;
})
.AddPubSubDeadLetterSender(opts => // enable dead letter
{
opts.Topic = "DL";
});
[CloudEvent] // register event with default pubsub name and topic
public record OrderCancelled(Guid OrderId, string Reason);
[CloudEvent(PubSubName = "redis", Topic = "another-topic", Type = "a-custom-type")]
public record OrderCancelled(Guid OrderId, string Reason);
var pubsub = serviceProvider.GetRequiredService<ICloudEventPubSub>();
await pubsub.PublishAsync(new OrderCancelled(order.Id, reason));
public class OrderCancelledHandler : ICloudEventHandler<OrderCancelled>
{
public async Task HandleAsync(CloudEvent<PingEvent> cloudEvent, CancellationToken token)
{
// ...
}
}
The benchmark result on a 4*2.4GHz Core VM:
Kafka | Redis | |
---|---|---|
Publish | ~100k/s | ~90k/s |
Subscribe | ~150k/s | ~40k/s |
The benchmark code is located at perf/CloudEventTester