2017-08-20 129 views
-1

接收来自wildfly JMS队列消息从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异步方式侦听队列,我可以从队列中获取消息。 如何解决它?我花了2天时间解决它,我真的没有想到,任何人都可以帮助我?Thx!Thx!Thx!

回答

0

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

你有的代码片段,因为我看到它使用psuedo同步方法。如果必须将其用作MDB,则必须实现消息驱动Bean(EJB资源)或消息监听器。

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

+0

使用异步方式获取消息是否属实?但我只是想用同步的方式在wildfly中从jms队列接收消息,代码不会抛出任何异常。 –

+0

您可以使用同步的方式来获取消息,您应该a)将请求与响应匹配,因为订单或处理没有保证 - 一个应用程序可能会回复发布消息可能比另一个应用程序更快b)在确认之前要轮询多久消息为“丢失”。如果你正在得到一个特定的堆栈跟踪,请发布你的问题 –

0

我没有看到你调用javax.jms.Connection.start()的地方。实际上,它看起来不像你甚至有一个对用于javax.jms.MessageConsumer的javax.jms.Connection实例的引用。如果你没有对javax.jms.Connection的引用,那么你不能调用start(),并且当你完成后你不能调用close(),所以你会泄漏连接。

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