Java 8 我的channel.basicConsume为什么不等待消息
每当我启动以下代码时:Java 8 我的channel.basicConsume为什么不等待消息,java-8,rabbitmq,message-queue,Java 8,Rabbitmq,Message Queue,每当我启动以下代码时: ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); String exchangeName = "direct_logs";
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String exchangeName = "direct_logs";
channel.exchangeDeclare(exchangeName, "direct");
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, exchangeName, "red");
channel.basicQos(1);
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body) throws IOException{
String message = new String(body, "UTF-8");
System.out.println(message);
System.out.println("message received");
}
};
channel.basicConsume(queueName, true, consumer);
它不会像文档中暗示的那样开始一个无休止的循环。相反,它会立即停止。
我能让它使用一段时间的唯一方法是用循环替换channel.basicConsume
,如下所示:
DateTime startedAt = new DateTime();
DateTime stopAt = startedAt.plusSeconds(60);
long i=0;
try {
while (stopAt.compareTo(new DateTime()) > 0) {
channel.basicConsume(queueName, true, consumer);
i++;
}
}finally {
System.out.println(new DateTime());
System.out.println(startedAt);
System.out.println(stopAt);
System.out.println(i);
}
一定有更好的方法来暂时听消息,对吗?我错过了什么?
它立即停止收听。你确定它正在停止吗?
basicConsume
所做的是注册一个消费者来监听一个特定的队列,这样就不需要在循环中执行它。您只执行一次,只要消息到达,就会调用您传递的消费者
实例的handleDelivery
方法
rabbitmq库创建的线程应该防止JVM退出。为了退出程序,您应该实际调用connection.close()
以下是rabbitmq的完整接收器示例:
它实际上和你的差不多。我也有同样的问题。原因是我在最后给connection.close打电话。但是,basicConsume()方法不会在当前线程上阻塞,而是在其他线程上阻塞,因此会立即调用它后面的代码,即connection.close()。如果您确实需要停止执行线程,直到消息被使用,您可以实现简单的循环器模式类:
class Looper {
private boolean exit = false;
void loop() {
while (true) {
if (exit) {
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void exit() {
this.exit = true;
}
}
A那么,在阅读这样的消息时,您可以应用此循环器:
public String basicConsumeMessage(String queue) {
final String[] messageBody = new String[1];
try {
consChannel.basicConsume(queue, new DefaultConsumer(consChannel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) {
deliveryTag = envelope.getDeliveryTag();
messageBody[0] = new String(body, StandardCharsets.UTF_8);
looper.exit();
}
});
} catch (IOException e) {
throw new JiraTransportError(e);
}
looper.loop();
return messageBody[0];
}
请注意looper.loop()和looper.exit()方法是如何使用的。您是否有任何异常,例如ConnectException:Connection Rejected?