【问题标题】:JBoss JMS MessageConsumer waits indefinitely for response messageJBoss JMS MessageConsumer 无限期地等待响应消息
【发布时间】:2016-02-19 16:34:28
【问题描述】:

我正在尝试在 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() 或响应将发送到其他不同的接收器,这不会发生在这里(据我所知,这些类之外的代码中还没有其他消息传递部分)

所以我想我的问题是,上面的代码应该有效还是我缺少对 JMS 流程的一些基本理解?

【问题讨论】:

    标签: jboss jms


    【解决方案1】:

    所以..我坚持了下来,并且成功了。

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

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

    必须改为:

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

    对于客户端和服务器。

    【讨论】:

    • 虽然我仍然不确定我为什么要做出这个改变,但如果有人能对此有所了解,我很感兴趣!
    • 我现在知道为什么了!我正在有效地执行以下取自 Oracle JMS 文档的操作!如果您尝试使用请求/回复机制,即您发送消息然后尝试在同一事务中接收对已发送消息的回复,则程序将挂起,因为在提交事务之前无法进行发送。下面的代码片段说明了这个问题: // 不要这样做! outMsg.setJMSReplyTo(replyQueue);生产者.send(outQueue, outMsg);消费者 = session.createConsumer(replyQueue); inMsg = 消费者.receive(); session.commit();
    【解决方案2】:

    我现在知道为什么了!我正在有效地执行以下取自 Oracle JMS 文档的操作!

    如果您尝试使用请求/回复机制,即您发送消息,然后尝试在同一事务中接收对已发送消息的回复,则程序将挂起,因为在事务完成之前无法进行发送坚定的。下面的代码片段说明了这个问题:

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

    【讨论】:

      猜你喜欢
      • 2022-08-10
      • 2015-12-09
      • 2012-05-12
      • 2011-01-29
      • 2014-11-26
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      相关资源
      最近更新 更多