当前位置: 首页 > 知识库问答 >
问题:

java spring boot amqp两个行为不同的侦听器

昝唯
2023-03-14

我是spring amqp的新手,我想创建两个行为不同的听众。问题是,我在编译时不知道队列名称,因此无法使用此解决方案。

我想做的事情是:从“sidechannel”队列中读取(然后删除)第一条消息,它应该是这样的{“queues”:[“queue1”,“queue2”]}。

现在从queue1和queue2读取(然后删除)第一条消息。之后,转至步骤1,阅读侧频道的第一条消息

正如您在下面的代码中所看到的,我试图创建两个具有不同侦听器的SimpleMessageListenerContainer,但它并没有像我想象的那样工作。

我的代码:

@SpringBootApplication
public class Main implements CommandLineRunner {

final static String queueName = "sidechannel";

@Autowired
AnnotationConfigApplicationContext context;

@Autowired
RabbitTemplate rabbitTemplate;

@Bean
Queue queue() {
    return new Queue(queueName, false);
}

@Bean
TopicExchange exchange() {
    return new TopicExchange("spring-boot-exchange");
}

@Bean
Binding binding(Queue queue, TopicExchange exchange) {
    return BindingBuilder.bind(queue).to(exchange).with(queueName);
}

@Bean
public ConnectionFactory rabbitConnectionFactory() {
    CachingConnectionFactory connectionFactory =
            new CachingConnectionFactory("localhost");
    connectionFactory.setUsername("guest");
    connectionFactory.setPassword("guest");
    return connectionFactory;
}

@Bean
public SimpleMessageListenerContainer messageListenerContainer() {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(rabbitConnectionFactory());
    container.setQueueNames(queueName);
    container.setMessageListener(sidechannelListener());
    return container;
}

@Bean
public SimpleMessageListenerContainer messageListenerContainer2() {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(rabbitConnectionFactory());
    container.setQueueNames("queue1","queue2");
    container.setMessageListener(queueListener());
    return container;
}



@Bean
public MessageListener sidechannelListener() {
    return message -> {
        String msg = new String(message.getBody());
        System.out.println(msg);
        try {
            Map<String, Object> map = html" target="_blank">jsonToMap(msg);
            for (String name : (ArrayList<String>) map.get("queues")) {
                System.out.println("Waiting for " + name + " message");
                rabbitTemplate.receive(name);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    };
}

@Bean
public MessageListener queueListener() {
    return message -> {
        String msg = new String(message.getBody());
        System.out.println("Received message: ");
        System.out.println(msg);
    };
}


public static void main(String[] args) throws InterruptedException {
    SpringApplication.run(Main.class, args);
}

@Override
public void run(String... args) throws Exception {
    rabbitTemplate.setReceiveTimeout(-1);

    while(true) {
        System.out.println("Waiting for side channel message");
        rabbitTemplate.receive(queueName);
    }
//        context.close();
}
}

首先,由于某种原因,侧通道队列中的消息在处理后不会删除。其次,当我期待这样的输出时:

Waiting for side channel message
{"queues":["queue1","queue2"]}
Waiting for queue1 message
Received message:
"message from queue1"
Waiting for queue2 message
"message from queue2"
Waiting for side channel message

即使我在这些不同的队列上收到消息,也不会发生任何事情(因为RabbitTemplate.setReceiveTimeout(-1);),但不知何故,它会对我收到的每条消息做出反应...

此外,我不明白的是,如果我首先向sid0008 nel发送消息,然后向queue1发送消息,它会像这样:

Waiting for side channel message
{"queues":["queue1","queue2"]}
Waiting for queue1 message
Received message:
"message from queue1"

现在,如果我向queue1发送另一条(第二条)消息,它会打印出消息,然后等待queue2消息

所以需要两条消息才能继续循环。。。我不知道我做错了什么。

共有1个答案

孙弘博
2023-03-14

你似乎在混合各种范式;您有消息驱动的侦听器容器,并且还使用轮询(template.receive())。通常,queue1、queue2的容器已经处理了来自这些队列的消息,并且

            System.out.println("Waiting for " + name + " message");
            rabbitTemplate.receive(name);

如果超时为

 类似资料:
  • 我有一个监听两个不同端口的TCP服务器。我创建了两个不同的套接字,一个在端口8888上,一个在端口6634上。我监听这些端口,然后我在FD_SET中添加两个套接字,并将它们传递给Select()函数...当套接字准备好读取时,我检查FD_ISSET,看看哪个端口上有消息要读取。 不管怎样,当我连接到8888端口时,构思是成功的,我可以向服务器发送和接收。。。当我在客户端ctrl c时,选择函数再次

  • 问题内容: 我需要使用同一端口收听2个不同的多播组。会从和那里听。两个多播组都使用相同的文件,但我无法控制它。 运行程序时,我在每个程序中都接收到两个多播流,即和上广播的数据包。我怀疑问题是由于通用端口引起的。这是我用来订阅多播的代码: 如何在每个程序中过滤特定的多播组? 问题答案: 如果你改变 至 您可能会获得更大的成功。 (如果您更改程序以使用,则可以使其适应未来。)

  • 问题内容: 我有一个,并且里面有两个。当我按下一个键时,他们两个都必须收听此键事件并采取行动。我要处理所有键盘事件,并将它们传递给两个s。你知道怎么做吗? 编辑:由于他们必须做不同的事情,所以我需要两个不同的侦听器,对不起您不明确。 Edit2:我编写了一个简单的代码来向您展示问题。当我按下向上键时,两个显示的s都必须更改其字符串。在此代码中,只有其中一个实际反应! 问题答案: 代替,使用 按键绑

  • 其中一个测试通过,另一个给出以下错误: java.lang.ClassCastException:类org.springframework.http.ResponseEntity不能强制转换为类org.junit.jupiter.api.function.executable(org.springframework.http.ResponseEntity和org.junit.jupiter.api

  • 问题内容: 我有两个分别称为“左”和“右”。“左”按钮将矩形对象向左移动,“右”按钮将其向右移动。我在班上有一个充当单击任一按钮时的侦听器。但是,我希望单击每个动作时都会发生不同的动作。如何区分点击的? 问题答案: 将actionCommand设置到每个按钮。 //将动作命令设置到两个按钮上。 更新:

  • 我能否向社区咨询一下,听多个主题的最佳方式是什么,每个主题都包含一个不同类别的信息? 在过去的几天里,我一直在玩Spring Kafka。到目前为止我的思考过程: