Why is my RabbitMQ consumer receiving all messages when I'm specifying the topic I want to receive?

拥有回忆 提交于 2021-01-07 01:45:13

问题


I have different message types on the queue and I'm trying to create multiple C# consumers that each just take a certain type off the queue.

Apparently, I'm supposed to be able to specify the routing key, like shown here, to get just those messages:

channel.QueueBind(queue: queueName, exchange: "SandboxEventBus", routingKey: "MessageEvent");

No matter why I try, I get all of the messages from the queue and not just the ones with that routing key. What am I missing?

This is the class:

public static class RabbitReceiver
{
    public static void PullFromQueue(string caller, int sleepTimeInMilliseconds)
    {
        string hostName = "localhost";
        string queueName = "Sandbox.v1";

        var factory = new ConnectionFactory { HostName = hostName, UserName = "guest", Password = "guest", Port = 6003 };

        var connection = factory.CreateConnection();
        var channel = connection.CreateModel();

        var arguments = new Dictionary<string, object>();
        arguments.Add("x-message-ttl", 864000000); // Not sure why I have to specify this. Got an exception if I didn't.
        //arguments.Add("topic", "MessageEvent");

        channel.BasicQos(0, 1, false);

        // Enabling these lines doesn't change anything. It was part of my effort of trying different things.
        //channel.ExchangeDeclare("SandboxEventBus", "topic", durable: true); // topic is case-sensitive
        //channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: arguments);
        channel.QueueBind(queue: queueName, exchange: "SandboxEventBus", routingKey: "MessageEvent");

        var consumer = new EventingBasicConsumer(channel);

        consumer.Received += (model, eventArgs) =>
        {
            var body = eventArgs.Body.ToArray();
            var message = Encoding.UTF8.GetString(body);
            Console.WriteLine($"Message: {message}");
            Console.WriteLine($"{caller} - Pausing {sleepTimeInMilliseconds} ms before getting next message (so we can watch the Rabbit dashboard update).");
            Thread.Sleep(sleepTimeInMilliseconds);

            // This should probably go in a finally block.
            channel.BasicAck(eventArgs.DeliveryTag, false);
        };

        channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer);
    }
}

Here is the publishing code. I'm simply publishing two different message types.

public class MessagePublisherService : BackgroundService
{
    private readonly ICapPublisher _capBus;

    public MessagePublisherService(ICapPublisher capPublisher)
    {
        _capBus = capPublisher;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // This publishes messages. To get the messages off the queue, run the RabbitMQ project in this solution.

        try
        {
            // To have a different event, add this.
            await _capBus.PublishAsync(nameof(SnuhEvent), new SnuhEvent());
            Console.WriteLine($"Published message {nameof(SnuhEvent)}.");

            for (int i = 1; i <= 10; i++)
            {
                //_capBus.Publish(nameof(MessageEvent), new MessageEvent(i));
                await _capBus.PublishAsync(nameof(MessageEvent), new MessageEvent(i));
                Console.WriteLine($"Published message {i}.");
            }                
        }
        catch (Exception ex)
        {
            Console.WriteLine("In catch block of publisher.");
            Console.WriteLine(ex);
        }
    }
}

And here is the queue. Notice each message type shows as a different routing key.

Here is the RMQ code in Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCap(x =>
        {
            x.UseSqlServer("Server=localhost; Database=Sandbox; Integrated Security=true;");

            x.DefaultGroup = "Sandbox";
            x.FailedRetryCount = 3;
            x.FailedRetryInterval = 2; // CAP will invoke the subscriber again if not finished in N seconds.

            x.UseRabbitMQ(conf =>
            {
                conf.ExchangeName = "SandboxEventBus";
                conf.ConnectionFactoryOptions = x =>
                {
                    x.Uri = BuildRabbitUri();
                };
            });
        });

        services.AddHostedService<MessagePublisherService>();
    }

    public static Uri BuildRabbitUri()
    {
        string protocol = "amqp";
        string userName = "guest";
        string password = "guest";
        string host = "localhost";
        string port = "6003";

        return new Uri(protocol + "://" + userName + ":" + password + "@" + host + ":" + port);
    }

来源:https://stackoverflow.com/questions/65308405/why-is-my-rabbitmq-consumer-receiving-all-messages-when-im-specifying-the-topic

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!