【问题标题】:Read synchronous (i.e. "receive" instead of listener)读取同步(即“接收”而不是侦听器)
【发布时间】:2014-06-26 03:56:07
【问题描述】:

以下代码 sn-p(独立 Java 应用程序)永远不会在队列中找到任何消息,而使用消息侦听器实现同一客户端时(使用 Glassfish 3.1):

ctx = new InitialContext();
connectionFactory = (ConnectionFactory) ctx.lookup("foo.Factory");

partsQueue = (Queue) ctx.lookup("foo.PartsQueue");

conn = connectionFactory.createConnection();
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
consumer = session.createConsumer(partsQueue);

conn.start();

Message msg = null;
int cnt = -1;
do {
    cnt++;
    msg = consumer.receiveNoWait();
} while (msg != null);

        System.out.println("cnt: " + cnt);

如果我在创建消费者后使用以下代码,监听器会找到消息并成功消费:

listener = new AssemblerListener(this);
consumer.setMessageListener(listener);
System.out.println("waiting for msgs...");
conn.start();

如前所述,独立的 Java 客户端,我并不想在 MDB 中同步做某事。有任何想法吗?没有找到任何提示为什么同步读取在这里不起作用。在这种情况下,使用消息侦听器不是最佳选择,因为有时我必须使用不同的过滤器读取两条消息。

【问题讨论】:

  • 所以第一个代码永远不会停止? (while 循环)
  • 它会立即停止并输出 0。
  • 所以你从receiveNoWait 得到的东西不是你想要的吗?
  • 我只从 receiveNoWait() 返回了 null (就像队列中没有消息一样)。使用侦听器时,我会收到所有消息。

标签: java glassfish jms synchronous


【解决方案1】:

这是我接收消息的方式:

    ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(url);

    // Getting JMS connection from the server
    ConnectionFactory connectionFactory= activeMQConnectionFactory;

    Connection connection = connectionFactory.createConnection();

    // Creating session for sending messages
    Session session = connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);


    // Getting the queue 'TESTQUEUE'
    Destination destination = session.createQueue("queue_name");

    // MessageConsumer is used for receiving (consuming) messages

    MessageConsumer consumer = session.createConsumer(destination);

    connection.start();        

    // Here we receive the message.
    // By default this call is blocking, which means it will wait
    // for a message to arrive on the queue.
    Message message= consumer.receive(500);
    while(message!= null)
    {

        // There are many types of Message and TextMessage
        // is just one of them. Producer sent us a TextMessage
        // so we must cast to it to get access to its .getText()
        // method.
        if (message instanceof TextMessage) 
        {
            TextMessage textMessage = (TextMessage) message;
       //     BytesMessage Byte

            System.out.println("Received message '"+ textMessage.getText() + "'");
        }           
        message = consumer.receive(1);
      }

【讨论】:

  • 非常感谢您的样品。有两个问题:第一个问题是队列的目的地而不是 ctx.lookup,尽管我真的不明白为什么这次我需要目的地,但如果我使用消息侦听器则不需要。 receive(500) 可以正常工作,receive(50) 也可以,但是 receive(5) 不能,因为 receiveNoWait() 也不能。 (我将这种行为称为“错误”,或者有什么方法有用吗?)
  • 我曾经遇到过这样的行为:即使队列中有消息,receiveNoWait() 也不给我消息。这发生在队列上的 400 多条消息中。我认为这确实是一个“错误”,我认为 Apache 也承认这是一个错误
【解决方案2】:

consumer.receiveNoWait() 返回 null 如果当时队列是空的。 如果它为空,您的代码不会再次尝试接收消息。

您应该继续循环或使用consumer.receive(),这将阻塞直到消息可用

【讨论】:

  • 队列不为空。我还有另外两段代码,一段使用 QueueBrowser 列出消息,一段使用消息侦听器(原始问题中的第二个代码 sn-p)我在此版本失败后运行。因此,消息在队列中,可以使用消息侦听器来消费,只是不能同步。
  • 如果你使用receive 而不是receiveNoWait 它会永远阻塞?
  • 原来没有。问题是我没有按照 Michael A 的建议使用 Destination。现在可以了。
猜你喜欢
  • 2019-07-20
  • 2013-02-02
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
相关资源
最近更新 更多