C# 将消息定向到消费者

C# 将消息定向到消费者,c#,azure,azure-eventhub,C#,Azure,Azure Eventhub,我的客户端正在尝试向接收方发送消息。然而,我注意到,接收者有时没有接收到客户端发送的所有消息,因此丢失了一些消息(不确定问题出在哪里?客户端还是接收者)。 任何关于为什么会发生这种情况的建议。这就是我目前正在做的事情 在接收端,这就是我正在做的 这是事件处理器 async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)

我的客户端正在尝试向接收方发送消息。然而,我注意到,接收者有时没有接收到客户端发送的所有消息,因此丢失了一些消息(不确定问题出在哪里?客户端还是接收者)。 任何关于为什么会发生这种情况的建议。这就是我目前正在做的事情

在接收端,这就是我正在做的

这是事件处理器

        async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
        {
            foreach (var eventData in messages)
            {
                var data = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
            }
        }

如何将消息定向到特定的使用者

只有当有两个或多个事件处理器主机从同一使用者组读取时,才会发生这种情况

如果您有32个分区的事件中心和2个从同一消费群体读取的事件处理器主机。然后,每个事件处理器主机将从16个分区中读取数据,以此类推

类似地,如果4个事件处理器主机并行地从同一消费者组读取数据,那么每个都将从8个分区读取数据


检查是否有2台或更多的事件处理器主机在同一消费者组上运行。

我已经测试了您的代码并对其进行了轻微修改(不同的EventProcessorHost构造函数重载,并在使用消息后添加了CheckpointAsync),然后做了一些测试

通过使用默认实现和默认EventProcessorOptions(EventProcessorOptions.DefaultOptions),我可以说,在使用消息时,我确实经历了一些延迟,但所有消息都已成功处理。 因此,有时我似乎没有从某个分区获得消息,但经过一段时间后,所有消息都会到达

您可以找到为我工作的实际修改代码。这是一个简单的控制台应用程序,如果有东西到达,它会打印到控制台

        string processorHostName = Guid.NewGuid().ToString();
        var Options = new EventProcessorOptions()
        {
            MaxBatchSize = 1, //not required to make it working, just for testing
        };
        Options.SetExceptionHandler((ex) =>
        {
            System.Diagnostics.Debug.WriteLine($"Exception : {ex}");
        });
        var eventHubCS = "event hub connection string";
        var storageCS = "storage connection string";
        var containerName = "test";
        var eventHubname = "test2";
        EventProcessorHost eventProcessorHost = new EventProcessorHost(eventHubname, "$Default", eventHubCS, storageCS, containerName);
        eventProcessorHost.RegisterEventProcessorAsync<MyEventProcessor>(Options).Wait();
string processorHostName=Guid.NewGuid().ToString();
var Options=new EventProcessorOptions()
{
MaxBatchSize=1,//不需要使其工作,仅用于测试
};
Options.SetExceptionHandler((ex)=>
{
System.Diagnostics.Debug.WriteLine($“异常:{ex}”);
});
var eventHubCS=“事件中心连接字符串”;
var storageCS=“存储连接字符串”;
var containerName=“测试”;
var eventHubname=“test2”;
EventProcessorHost EventProcessorHost=新的EventProcessorHost(eventHubname,“$Default”,eventHubCS,storageCS,containerName);
eventProcessorHost.RegisterEventProcessorAsync(选项).Wait();
为了将消息发送到事件中心并进行测试,我使用了这个


我正在使用eventhub官方文档中的示例代码,用于和

我有两个消费群体:$Defaultnewcg。假设您有两个客户机,客户机_1使用默认的消费者组($default),客户机_2使用另一个消费者组(newcg)

首先,在创建发送客户端之后,在
SendMessagesToEventHub
方法中,我们需要添加一个具有值的属性。该值应为消费者组名称。示例代码如下所示:

    private static async Task SendMessagesToEventHub(int numMessagesToSend)
    {
        for (var i = 0; i < numMessagesToSend; i++)
        {
            try
            {
                var message = "444 Message";
                Console.WriteLine($"Sending message: {message}");
                EventData mydata = new EventData(Encoding.UTF8.GetBytes(message));

                //here, we add a property named "cg", it's value is the consumer group. By setting this property, then we can read this message via this specified consumer group.
                mydata.Properties.Add("cg", "newcg");

                await eventHubClient.SendAsync(mydata);

            }
            catch (Exception exception)
            {
                Console.WriteLine($"{DateTime.Now} > Exception: {exception.Message}");
            }

            await Task.Delay(10);
        }

        Console.WriteLine($"{numMessagesToSend} messages sent.");
    }
            public Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
            {
                foreach (var eventData in messages)
                {
                    //filter the data here, using another consumer group name
                    if (eventData.Properties["cg"].ToString() == "newcg")
                    {  
                       //other code
                    }
                   }

                 return context.CheckpointAsync();
               }
在另一个客户机中,比如client_2,它使用另一个消费群体,比如它的名字是newcg,我们可以按照client_1中的步骤进行操作,只需对
ProcessEventsAsync
方法做一些小的更改,如下所示:

    private static async Task SendMessagesToEventHub(int numMessagesToSend)
    {
        for (var i = 0; i < numMessagesToSend; i++)
        {
            try
            {
                var message = "444 Message";
                Console.WriteLine($"Sending message: {message}");
                EventData mydata = new EventData(Encoding.UTF8.GetBytes(message));

                //here, we add a property named "cg", it's value is the consumer group. By setting this property, then we can read this message via this specified consumer group.
                mydata.Properties.Add("cg", "newcg");

                await eventHubClient.SendAsync(mydata);

            }
            catch (Exception exception)
            {
                Console.WriteLine($"{DateTime.Now} > Exception: {exception.Message}");
            }

            await Task.Delay(10);
        }

        Console.WriteLine($"{numMessagesToSend} messages sent.");
    }
            public Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
            {
                foreach (var eventData in messages)
                {
                    //filter the data here, using another consumer group name
                    if (eventData.Properties["cg"].ToString() == "newcg")
                    {  
                       //other code
                    }
                   }

                 return context.CheckpointAsync();
               }
公共任务流程事件同步(分区上下文,IEnumerable消息) { foreach(消息中的var eventData) { //使用其他消费者组名称在此处筛选数据 if(eventData.Properties[“cg”].ToString()=“newcg”) { //其他代码 } } 返回context.CheckpointAsync(); }
能否提供发送客户端的完整代码?在发送客户端中,如何调用自定义方法send(string content)?在接收方,我看到您在CloseAsync()方法中调用CheckpointAsync(),但在官方文档中,CheckpointAsync()是在ProcessEventsAsync()方法中设置的。如果您没有一些自定义要求,您应该遵循发送/接收的。是的,让我更新code@IvanYang用户调用SendMessage,该消息调用Send。我非常怀疑在CloseAsync()中错放CheckpointAsync()的原因,因为在发送消息时不会调用CloseAsync()。您可以共享AsyncDispatchEvent方法吗?我刚试过,它不能在这里重新编程。你是说它直接调用SendMessage()方法,每次只发送一条消息?如果是这样的话,我会按照你的代码进行调试。是的,看起来我需要消费者。谢谢你的建议。