-1

从 WildFly JMS 队列接收消息时,我遇到了一个棘手的问题。我的代码如下:

Session produceSession = connectionFactory.createConnection().createSession(false, Session
                    .CLIENT_ACKNOWLEDGE);
            Session consumerSession = connectionFactory.createConnection().createSession(false, Session
                    .CLIENT_ACKNOWLEDGE);
            ApsSchedule apsSchedule = new ApsSchedule();

            boolean success;
            MessageProducer messageProducer = produceSession.createProducer(outQueueMaxusOrder);
            success = apsSchedule.sendD90Order(produceSession,messageProducer, d90OrderAps);
            if (!success) {
                logger.error("Can't send APS schedule msg ");
            } else {
                MessageConsumer consumer = consumerSession.createConsumer(inQueueDeliveryDate);
                data = apsSchedule.receiveD90Result(consumerSession,consumer);
            }

然后进入receiveD90Result():

public DeliveryData receiveD90Result(Session session, MessageConsumer consumer) {
    DeliveryData data = null;
    try {
         Message message = consumer.receive(10000);

        if (message == null) {
            return null;
        }
        TextMessage msg = (TextMessage) message;
        String text = msg.getText();
        logger.debug("Receive APS d90 result: {}", text);

        ObjectMapper mapper = new ObjectMapper();
        data = mapper.readValue(text, DeliveryData.class);
    } catch (JMSException je) {
        logger.error("Can't receive APS d90 order result: {}", je.getMessage());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            consumer.close();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
    return data;
}

但是在实施时consumer.receive(10000),项目无法从队列中获取消息。如果我使用 MDB 的异步方式来监听队列,我可以从队列中获取消息。如何解决?

4

2 回答 2

0

我看不到你在哪里调用 javax.jms.Connection.start()。事实上,看起来您甚至没有对用于您的 javax.jms.MessageConsumer 的 javax.jms.Connection 实例的引用。如果您没有对 javax.jms.Connection 的引用,那么您将无法调用 start() 并且在完成后也无法调用 close() ,因此您将泄漏连接。

此外,连接是“重”对象,旨在重复使用。您应该为生产者和消费者创建一个连接。此外,如果您的应用程序不打算从多个线程中使用 javax.jms.Session,那么您也不需要多个会话。

于 2017-09-01T19:54:04.523 回答
0

您可以选择多种模式从队列中获取消息。默认情况下,消息队列在使用中是异步的。然而,在某些情况下,您希望同步读取它,例如发送带有帐号的消息并使用另一个队列读取响应并将其与消息 ID 或消息相关 ID 匹配。当您执行接收时,程序正在等待消息在接收中指定的轮询间隔内到达。

正如我所见,您拥有的代码片段使用伪同步方法。如果您必须将其用作 MDB ,则必须实现消息驱动 bean(EJB 资源)或消息侦听器。

MDB/Message Listener 的工作方式更加基于事件,而不是超时轮询(如接收),您实现了一个名为 onMessage() 的回调,每次有消息时都会调用该回调。这不是同步调用,而是异步的。您的应用程序可能需要在设计方面进行一些更改。

于 2017-08-20T07:46:22.320 回答