2017-08-20 6 views
-1

ich ein knorrigen Problem gestoßen, wenn die Nachricht von Wildfly jms Warteschlange empfange, ist mein Code Schlag:Wie Nachricht von Wildfly jms Warteschlange erhalten Verbraucher mit

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

dann in die receiveD90Result bekommen():

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

Bei der Implementierung von consumer.receive (10000) kann das Projekt jedoch keine Nachricht aus der Warteschlange abrufen. Wenn ich asynchrone Art von MDB verwenden, um die Warteschlange zu überwachen, kann ich die Nachricht aus der Warteschlange abrufen. Wie löst man es? Ich habe 2 Tage damit verbracht es zu lösen, ich bin wirklich verrückt. Könnte mir jemand helfen? Thx! Thx! Thx!

Antwort

0

Es gibt mehrere Modi, die Sie auswählen können, um eine Nachricht aus der Warteschlange zu erhalten. Nachrichtenwarteschlangen sind standardmäßig in der Verwendung asynchron. Es gibt jedoch Fälle, in denen Sie es synchron lesen möchten, z. B. Senden einer Nachricht mit Kontonummer und Verwenden einer anderen Warteschlange zum Lesen der Antwort und Abgleichen mit einer Nachrichten-ID oder einer Nachrichtenkorrelations-ID. Wenn Sie einen Empfang durchführen, wartet das Programm auf eine Nachricht, die innerhalb des Abrufintervalls ankommt, das in receive angegeben ist.

Das Code-Snippet, das Sie haben, wie ich sehe, verwendet den pseudo-synchronen Ansatz. Wenn Sie es als MDB verwenden müssen, müssen Sie Message Driven Bean (EJB Resource) oder Message Listener implementieren.

Die Art und Weise, wie MDB/Message Listener funktioniert, ist ereignisbasierter, statt einer Abfrage mit einem Timeout (wie der Empfang) implementieren Sie einen Callback namens onMessage(), der jedes Mal aufgerufen wird, wenn eine Nachricht vorhanden ist. Statt eines synchronen Aufrufs wird dies asynchron. Ihre Anwendung erfordert möglicherweise einige Änderungen in Bezug auf das Design.

+0

Stimmt es, dass asynchrone Art und Weise, um Nachricht zu bekommen? Aber ich möchte nur synchrone Weise verwenden, um Nachricht von JMS-Warteschlange in Wildfly zu erhalten, wird der Code keine Ausnahme auslösen. –

+0

Sie können synchrone Art und Weise verwenden, um die Nachricht zu erhalten, sollten Sie a) die Anfrage mit der Antwort übereinstimmen, weil Bestellung oder Verarbeitung nicht garantiert ist - eine Anwendung kann Antwort die Nachricht schneller als eine andere b) Wie lange werden Sie vor der Bestätigung abfragen Nachricht als "verloren". Wenn Sie eine bestimmte Stack-Trace erhalten, posten Sie bitte Ihre Frage –

0

Ich sehe nicht, wo Sie javax.jms.Connection.start() aufrufen. In der Tat sieht es nicht so aus, als hätten Sie sogar einen Verweis auf die javax.jms.Connection-Instanz, die für Ihren javax.jms.MessageConsumer verwendet wird. Wenn Sie keinen Verweis auf die Datei javax.jms.Connection haben, können Sie start() nicht aufrufen, und Sie können close() nicht aufrufen, wenn Sie fertig sind, sodass Verbindungen verloren gehen.

Darüber hinaus sind Verbindungen "schwere" Objekte und sollen wiederverwendet werden. Sie sollten eine einzige Verbindung für den Hersteller und den Verbraucher erstellen. Wenn Ihre Anwendung nicht die javax.jms.Session aus mehreren Threads verwendet, benötigen Sie auch nicht mehrere Sitzungen.

Verwandte Themen