繁体   English   中英

指定主题时使用直接交换的 RabbitMQ

[英]RabbitMQ using Direct Exchange when Topic was specified

在我的应用程序中,我有 3 个类:
- 公司,为 3 个工作中的任何一个雇佣工人
- 工人,每人可以做2份工作
- 管理员,接收程序中所有消息的副本,并可以向所有公司、所有员工或每个人发送消息

我使用work.companies.companyName作为公司密钥, work.workers.workerName作为工人密钥,它们都使用默认交换和队列进行通信。 管理员通过admin Topic Exchange 接收消息。

问题出在管理员 -> 其他人的沟通上。 它的工作原理与直接交换完全一样 - 我可以获取 Companies 和 Workers 的任何名称,甚至像“#”、“company1.#”等,但他们不会收到任何东西,除非在管理员中我明确地使用“工作.companies.company1”。
我希望能够仅使用例如“work.companies.#”向所有公司发送消息。 我究竟做错了什么?

管理员.java:

public class Administrator
{
    public static void main(String[] args) throws IOException, TimeoutException
    {
        new Thread(new TopicListener("admin", ign -> {})).start();
        TopicWriter writer = new TopicWriter();
    // lots of code

主题监听器.java:

public class TopicListener implements Runnable
{
    private final String EXCHANGE_NAME = "space";
    private String key;
    private Consumer<String> msgHandler;

    public TopicListener(String key, Consumer<String> msgHandler)
    {
        this.key = key;
        this.msgHandler = msgHandler;
    }

    @Override
    public void run()
    {
        try
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();

            channel.exchangeDeclare(EXCHANGE_NAME, "topic");

            String queueName = channel.queueDeclare().getQueue();
            channel.queueBind(queueName, EXCHANGE_NAME, key);

            com.rabbitmq.client.Consumer consumer = new DefaultConsumer(channel)
            {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
                {
                    String msg = new String(body, StandardCharsets.UTF_8);
                    System.out.println("Received: \"" + msg + "\"");
                    msgHandler.accept(msg);
                }
            };

            channel.basicConsume(queueName, true, consumer);
        }
        catch (IOException | TimeoutException e)
        { e.printStackTrace(); }
    }
}

TopicWriter.java:

public class TopicWriter
{
    private final String EXCHANGE_NAME = "space";
    private final Channel channel;

    public TopicWriter() throws IOException, TimeoutException
    {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        this.channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
    }

    public void send(String msg, String key) throws IOException
    {
        channel.basicPublish(
                EXCHANGE_NAME,
                key,
                null,
                msg.getBytes(StandardCharsets.UTF_8));
    }
}

Company.java 包含:

new Thread(new TopicListener("space.agencies." + agencyID, ign -> {})).start();

Worker.java 包含:

new Thread(new TopicListener("space.carriers." + carrierID, consumer)).start();

我发现问题出在哪里:我试图使用 Topic 向每个人发送消息,在 RabbitMQ 中,Topic 用于指定谁应该接收消息。 "#" 或 "*" 应该在队列键声明中使用,而不是在使用给定键发送消息时使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM