2017-08-20 125 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,那麼您也不需要多個會話。