简体   繁体   English

如何使用消费者从wildfly jms队列接收消息

[英]How to receive message from wildfly jms queue using consumer

I encountered a knotty problem when receiving message from WildFly JMS queue.我在从 WildFly JMS 队列接收消息时遇到了一个棘手的问题。 My code is below:我的代码如下:

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);
            }

then getting into the receiveD90Result():然后进入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;
}

But when implementing the consumer.receive(10000) , the project can't get a message from queue.但是在实现consumer.receive(10000) ,项目无法从队列中获取消息。 If I use asynchronous way of MDB to listen the queue, I can get the message from queue.如果我使用MDB的异步方式来监听队列,我可以从队列中获取消息。 How to resolve it?如何解决?

There are multiple modes you can choose to get a message from the queue.您可以选择多种模式从队列中获取消息。 Message Queues are by default asynchronous in usage.默认情况下,消息队列在使用中是异步的。 There are however cases when you want to read it synchronously , for example sending a message with account number and using another queue to read the response and match it with a message id or a message correlation id.然而,有些情况下您希望同步读取它,例如发送带有帐号的消息并使用另一个队列读取响应并将其与消息 ID 或消息相关 ID 进行匹配。 When you do a receive , the program is waiting for a message to arrive within that polling interval specified in receive.当您执行接收时,程序正在等待消息在接收中指定的轮询间隔内到达。

The code snippet you have , as i see it uses the psuedo synchronous approach.您拥有的代码片段,正如我所见,它使用了伪同步方法。 If you have to use it as an MDB , you will have to implement message driven bean (EJB Resource) or message listener.如果必须将其用作 MDB ,则必须实现消息驱动 bean(EJB 资源)或消息侦听器。

The way that MDB/Message Listener works is more event based , instead of a poll with a timeout (like the receive) , you implement a callback called onMessage() that is invoked every time there is a message. MDB/消息侦听器的工作方式更多地基于事件,而不是带有超时的轮询(如接收),您实现了一个名为 onMessage() 的回调,每次有消息时都会调用该回调。 Instead of a synchronous call , this becomes asynchronous.这不是同步调用,而是异步的。 Your application may require some changes both in terms of design.您的应用程序可能需要在设计方面进行一些更改。

I don't see where you're calling javax.jms.Connection.start().我没有看到你在哪里调用 javax.jms.Connection.start()。 In fact, it doesn't look like you even have a reference to the javax.jms.Connection instance used for your javax.jms.MessageConsumer.事实上,看起来您甚至没有对用于 javax.jms.MessageConsumer 的 javax.jms.Connection 实例的引用。 If you don't have a reference to the javax.jms.Connection then you can't invoke start() and you can't invoke close() when you're done so you'll be leaking connections.如果您没有对 javax.jms.Connection 的引用,那么您将无法在完成后调用 start() 并且无法调用 close(),因此您将泄漏连接。

Furthermore, connections are "heavy" objects and are meant to be re-used.此外,连接是“重”对象,需要重复使用。 You should create a single connection for both the producer and consumer.您应该为生产者和消费者创建一个连接。 Also, if your application is not going to use the javax.jms.Session from multiple threads then you don't need multiple sessions either.此外,如果您的应用程序不打算使用来自多个线程的 javax.jms.Session,那么您也不需要多个会话。

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

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