簡體   English   中英

客戶消費者未收到JMS答復

[英]JMS reply not received by client consumer

我有一個客戶端,它向JMS MDB發送請求。 將消息發送 MDB可以很好地工作,但是我一輩子都無法弄清楚如何讓客戶端接收MDB發送回給它的響應。

編輯:客戶端代碼是使用@WebService的同一實例上的Web服務。 我不知道這是否會有所作為(例如,對於交易而言),但是除了這一問題之外,它似乎還是有效的。

MDB代碼:

private void sendReply(String replyData, javax.jms.Message requestMessage)
{
    try
    {
        logger.info("sendReply message received had ID: " + requestMessage.getJMSMessageID());
        logger.info("sendReply message getJMSReplyTo: " + requestMessage.getJMSReplyTo());

        Session session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);

        final Queue replyQueue = (Queue) requestMessage.getJMSReplyTo();
        MessageProducer producer = session.createProducer(replyQueue);
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

        TextMessage message = session.createTextMessage();
        message.setText(replyData);
        message.setJMSCorrelationID(requestMessage.getJMSMessageID());

        producer.send(message, DeliveryMode.PERSISTENT, 9, 60000);
        producer.close();

        logger.info("sendReply message returned had ID: " + message.getJMSMessageID());

        session.close();

        logger.debug("sendReply sent reply containing:\n" + replyData);
    }
    catch (Throwable e)
    {
        logger.warn("Exception in sendReply(): " + stackToString(e));
    }
}

客戶代碼:

connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(requestQueue);

Message message = null;

// Snip creation of message

producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
final Queue replyQueue = session.createTemporaryQueue();
message.setJMSReplyTo(replyQueue);
consumer = session.createConsumer(replyQueue);  
producer.send(message);
producer.close();

log.info("call message transmitted had  Message ID: " + message.getJMSMessageID());

TextMessage replyMessage = (TextMessage)consumer.receive(JMS_REPLY_TIMEOUT); // 30 seconds

log.info("call message returned had Correlation ID: " + replyMessage.getJMSCorrelationID());
log.info("call message returned had     Message ID: " + replyMessage.getJMSMessageID());

我每次運行此命令時,行TextMessage replyMessage = (TextMessage)consumer.receive(JMS_REPLY_TIMEOUT); 返回null。 每一次。 我究竟做錯了什么? MDB代碼成功運行-日志消息全部輸出相關數據,並且MDB收到的消息內容符合預期。 只是此回復消息,我無法上班。

我已經使用以下代碼瀏覽臨時隊列,並且看到了消息! 檢查消息ID,我發送的回復消息肯定在隊列中,但是調用consumer.receive(JMS_REPLY_TIMEOUT)仍返回null ...我根本無法弄清楚發生了什么。

log.info("Browsing Queue");
QueueBrowser browser = session.createBrowser(replyQueue);
final Enumeration<?> en = browser.getEnumeration();
while (en.hasMoreElements()) {
    Message m = (Message) en.nextElement();
    log.info("Found message in Queue with Browser with ID [{}] and CorrelID [{}]", m.getJMSMessageID(), m.getJMSCorrelationID());
}
browser.close();

我在具有Java 1.7.0_04 64位的Ubuntu 10.04上運行Glassfish 3.1.2.2。

編輯:我也嘗試過將發送和接收拆分為單獨的事務,如下所示:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private void sendMessage(final Session session, final Message message) throws JMSException {
    // Create a MessageProducer from the Session to the Topic or Queue
    final MessageProducer producer = session.createProducer(requestQueue);

    try {
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

        producer.send(message);
    }
    finally {
        producer.close();
    }
}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private TextMessage receiveMessage(Session session, Destination replyQueue) throws JMSException {
    final MessageConsumer consumer = session.createConsumer(replyQueue);
    try {
        final TextMessage m = (TextMessage)consumer.receive(JMS_REPLY_TIMEOUT);
        return m;
    }
    finally {
        consumer.close();
    }
}

但這並不能解決我的問題,盡管我承認我不確定這是否是確保這些方法中存在新事務所需要做的全部工作。

編輯:修改為以下方法的接收方法:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private TextMessage receiveMessage(Session session, Destination replyQueue) throws JMSException {
    final MessageConsumer consumer = session.createConsumer(replyQueue);
    try {
        log.info("Receiving message on Queue [{}]", replyQueue);
        final TextMessage m = (TextMessage)consumer.receive(JMS_REPLY_TIMEOUT);
        log.info("Received message [{}]", m);
        log.info("Browsing Queue");
        QueueBrowser browser = session.createBrowser((Queue) replyQueue);
        final Enumeration<?> en = browser.getEnumeration();
        while (en.hasMoreElements()) {
            Message mess = (Message) en.nextElement();
            log.info("Found message in Queue with Browser with ID [{}] and CorrelID [{}]", mess.getJMSMessageID(), mess.getJMSCorrelationID());
        }
        browser.close();
        return m;
    }
    finally {
        consumer.close();
    }
}

我得到的日志輸出是:

20130225200939808 CLIENT heartBeat Called.
20130225200939808 CLIENT heartBeat Sending Message...
20130225200940020 CLIENT callMAPSWebServiceMDB building TextMessage
20130225200940057 CLIENT Sending message
20130225200940064 CLIENT Sent message
20130225200940067 CLIENT message transmitted had  Message ID: ID:1-192.168.2.105(b5:49:dd:bf:5b:a6)-1-1361776180058
20130225200940077 CLIENT Receiving message on Queue [Oracle GlassFish(tm) Server MQ Destination
getName():      temporary_destination://queue/192.168.2.105/3170601277394174976/1
Class:          com.sun.messaging.jms.ra.TemporaryQueue
getVERSION():       3.0
isReadonly():       false
getProperties():    {imqDestinationName=temporary_destination://queue/192.168.2.105/3170601277394174976/1, imqDestinationDescription=A Description for the Destination Object}]
20130225200940183 SERVER Message Received
20130225200940757 SERVER Function called is: [heartBeat]
20130225200950759 SERVER sendReply message received had ID: ID:1-192.168.2.105(b5:49:dd:bf:5b:a6)-1-1361776180058
20130225200950760 SERVER sendReply message getJMSReplyTo: Oracle GlassFish(tm) Server MQ Destination
getName():      temporary_destination://queue/192.168.2.105/3170601277394174976/1
Class:          com.sun.messaging.jms.ra.TemporaryQueue
getVERSION():       3.0
isReadonly():       false
getProperties():    {imqDestinationName=temporary_destination://queue/192.168.2.105/3170601277394174976/1, imqDestinationDescription=A Description for the Destination Object}
20130225200950777 SERVER Sending reply message
20130225200950779 SERVER Sent reply message
20130225200950780 SERVER sendReply message returned had ID: ID:2-192.168.2.105(b5:49:dd:bf:5b:a6)-1-1361776190777
20130225200950781 SERVER MAPSWebServiceMDB Message Done
20130225201010078 CLIENT Received message [null]
20130225201010080 CLIENT Browsing Queue
20130225201010092 CLIENT Found message in Queue with Browser with ID [ID:2-192.168.2.105(b5:49:dd:bf:5b:a6)-1-1361776190777] and CorrelID [ID:1-192.168.2.105(b5:49:dd:bf:5b:a6)-1-1361776180058]

因此,盡管在隊列中等待了30秒鍾,但我一直沒有收到一直在隊列中的消息。 所以, 什么是錯 我在做什么嗎? 還是Glassfish的錯誤?

您必須添加

connection.start();

才能收到回復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM