JBoss JMS MessageConsumer无限期地等待响应消息

时间:2014-08-08 10:07:17

标签: jboss jms

我正在尝试使用JBoss上的JMS创建同步请求

MDB代码是:

@Resource(mappedName = "java:/ConnectionFactory")
private ConnectionFactory connectionFactory;


@Override
public void onMessage(Message message) {
    logger.info("Received message for client call");
    if (message instanceof ObjectMessage) {         
        Connection con = null;
        try {
            con = connectionFactory.createConnection();
            con.start();
            Requests requests = (Requests) ((ObjectMessage) message)
                    .getObject();
            String response = getClient().get(getRequest(requests));
            con = connectionFactory.createConnection();

            Session ses = con.createSession(true, Session.AUTO_ACKNOWLEDGE);

            MessageProducer producer = ses.createProducer(message
                    .getJMSReplyTo());
            TextMessage replyMsg = ses.createTextMessage();
            replyMsg.setJMSCorrelationID(message.getJMSCorrelationID());

            replyMsg.setText(response);
            logger.info("Sending reply to client call : " + response );
            producer.send(replyMsg);                

        } catch (JMSException e) {
            logger.severe(e.getMessage());
        } finally {
            if (con != null) {
                try {
                    con.close();
                } catch (Exception e2) {
                    logger.severe(e2.getMessage());
                }
            }
        }
    }
}

客户代码是:

@Resource(mappedName = "java:/ConnectionFactory")
private QueueConnectionFactory queueConnectionFactory;

@Resource(mappedName = "java:/queue/request")
private Queue requestQueue;

@Override
public Responses getResponses(Requests requests) {

    QueueConnection connection = null;
    try {
        connection = queueConnectionFactory.createQueueConnection();
        connection.start();
        QueueSession session = connection.createQueueSession(false,
                Session.AUTO_ACKNOWLEDGE);


        MessageProducer messageProducer = session
                .createProducer(requestQueue);

        ObjectMessage message = session.createObjectMessage();
        message.setObject(requests);
        TemporaryQueue temp = session.createTemporaryQueue();
        MessageConsumer consumer = session.createConsumer(temp);
        message.setJMSReplyTo(temp);
        messageProducer.send(message);

        Message response = consumer.receive();
        if (response instanceof TextMessage) {
            logger.info("Received response");
            return new Responses(null, ((TextMessage) response).getText());
        }
    } catch (JMSException e) {
        logger.severe(e.getMessage());
    } finally {
        if (connection != null) {
            try {
                connection.close();
            } catch (Exception e2) {
                logger.severe(e2.getMessage());
            }
        }
    }
    return null;
}

队列中收到的消息正常,响应消息已创建,MessageProducer无错误地发送响应,没有错误。然而,消费者只是坐下来无限期地等待。我还尝试创建一个单独的回复队列,而不是使用临时队列,结果是相同的。

我猜我错过了这个基本设置的东西,但我不能为我的生活看到我做错了什么。

没有其他代码,我在这上面读到的两件可能导致问题的事情是,没有调用connection.start()或者调用其他不同的接收器,而不是#39发生在这里(据我所知 - 这些类之外的代码还没有其他消息传递部分)

所以我想我的问题是,上述代码是否有效或者我是否缺少对JMS流程的基本了解?

2 个答案:

答案 0 :(得分:0)

所以..我坚持不懈,我让它发挥作用。

答案是,当我创建会话时,客户端和MDB中的事务处理属性必须设置为false:

Session ses = con.createSession(true, Session.AUTO_ACKNOWLEDGE);

必须改为:

Session ses = con.createSession(false, Session.AUTO_ACKNOWLEDGE);

用于客户端和服务器。

答案 1 :(得分:0)

我知道为什么现在!我正在有效地执行以下内容,该内容取自Oracle JMS文档!

如果您尝试使用请求/回复机制,即您发送邮件然后尝试在同一事务中接收对已发送邮件的回复,则程序将挂起,因为在事务发生之前无法发送承诺。以下代码片段说明了问题:

// Don’t do this!
outMsg.setJMSReplyTo(replyQueue);
producer.send(outQueue, outMsg);
consumer = session.createConsumer(replyQueue);
inMsg = consumer.receive();
session.commit();