简体   繁体   English

收到消息后关闭JMS会话和连接

[英]Close JMS session and connection after message received

I have a stateful session bean where I send and receive JMS messages. 我有一个有状态会话bean,可以在其中发送和接收JMS消息。 All the connection setup is handled manually, so the bean is holding instances of javax.jms.connection and javax.jms.session. 所有连接设置都是手动处理的,因此Bean包含javax.jms.connection和javax.jms.session的实例。 The bean also implements MessageListener to be able receive messages. Bean还实现了MessageListener以便能够接收消息。

Now, when I send a message, I create a temporary queue with session.createTemporaryQueue(). 现在,当我发送消息时,我使用session.createTemporaryQueue()创建一个临时队列。 I set the message.setJMSReplyTo() to this same temporary queue, and at last creates a consumer of this queue and sets the MessageListener to the same stateful session bean that all this is implemented in. 我将message.setJMSReplyTo()设置为相同的临时队列,最后创建该队列的使用者,并将MessageListener设置为在其中实现所有功能的同一有状态会话Bean。

I am abel to receive the message to the onMessage() method. 我很想收到消息到onMessage()方法。 However, I want to close the session and connection as soon as the message has been received, and this is apparently not allowed in the onMessage() method. 但是,我想在收到消息后立即关闭会话和连接,这显然在onMessage()方法中是不允许的。

So the question is: How can I close the session and connection once the message has been received? 因此问题是:收到消息后,如何关闭会话和连接? I must handle the connection setup manually and can not use a MDB. 我必须手动处理连接设置,并且不能使用MDB。

Note that: This is executed in the Java EE environment (GlassFish 4.0) 请注意:这是在Java EE环境(GlassFish 4.0)中执行的

EDIT: 编辑:

import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.inject.Inject;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import com.sun.messaging.ConnectionConfiguration;
import com.sun.messaging.QueueConnectionFactory;

@LocalBean
@Stateful
public class OpenMqClient implements MessageListener{
    private Connection connection;
    private Session session;
    private MessageConsumer responseConsumer;

    public OpenMqClient(){}

    public void sendMessage(String messageContent, String jmsBrokerUri, String queueName) {
        try{
            String host = System.getProperty("foo", jmsBrokerUri);
            QueueConnectionFactory cf = new QueueConnectionFactory();
            cf.setProperty(ConnectionConfiguration.imqAddressList, host);
            connection = null;
            session = null;

            //Setup connection
            connection = cf.createConnection();
            connection.start();
            session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

            //Setup queue and producer
            Queue queue = session.createQueue(queueName);
            MessageProducer producer = session.createProducer(queue);


            //Reply destination
            Queue responseQueue = session.createTemporaryQueue();
            responseConsumer = session.createConsumer(responseQueue);
            responseConsumer.setMessageListener(this);

            //Create message
            TextMessage textMessage = session.createTextMessage();
            textMessage.setJMSReplyTo(responseQueue);
            textMessage.setJMSCorrelationID("test0101");
            textMessage.setText(messageContent);

            producer.send(textMessage);
            System.out.println("Message sent");
        } catch (JMSException e) {
            e.printStackTrace();
            System.out.println("JMSException in Sender");
        }
    }

    @Override
    public void onMessage(Message arg0) {
        //On this event I want to close the session and connection, but it's not permitted
    }

}

Personally, this is how I would do it (note I haven't tested or added much error handling to this code). 就个人而言,这就是我的操作方式(请注意,我尚未对此代码进行测试或添加了很多错误处理)。

  1. Make the connection static - you can (probably should) reuse the same connection for all your beans unless you have a specific reason not to 将连接设为静态-可以(可能应该)对所有bean重新使用相同的连接,除非有特殊原因不这样做
  2. Close the session in a new thread 在新线程中关闭会话

     public class OpenMqClient implements MessageListener { private static Connection connection; private static final String mutex = "mutex"; private Session session; private MessageConsumer responseConsumer; public OpenMqClient() { if(connection == null) { synchronized(mutex) { if(connection == null) { String host = System.getProperty("foo", jmsBrokerUri); QueueConnectionFactory cf = new QueueConnectionFactory(); cf.setProperty(ConnectionConfiguration.imqAddressList, host); // Setup connection connection = cf.createConnection(); connection.start(); } } } } public void sendMessage(String messageContent, String jmsBrokerUri, String queueName) { try { session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // Setup queue and producer Queue queue = session.createQueue(queueName); MessageProducer producer = session.createProducer(queue); // Reply destination Queue responseQueue = session.createTemporaryQueue(); responseConsumer = session.createConsumer(responseQueue); responseConsumer.setMessageListener(this); // Create message TextMessage textMessage = session.createTextMessage(); textMessage.setJMSReplyTo(responseQueue); textMessage.setJMSCorrelationID("test0101"); textMessage.setText(messageContent); producer.send(textMessage); System.out.println("Message sent"); } catch (JMSException e) { e.printStackTrace(); System.out.println("JMSException in Sender"); } } @Override public void onMessage(Message arg0) { // do stuff new Thread( new Runnable() { @Override public void run() { if(session != null) try { session.close(); } catch (JMSException e) { e.printStackTrace(); } } } ).start(); } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM