如何从Web应用程序中侦听消息队列?(Tomcat,ActiveMQ)

Dim*_*ele 7 java queue tomcat activemq-classic jms

我很高兴改进在Apache Tomcat上运行的Web应用程序.一个ActiveMQ的 JMS服务器添加到发送和接收消息.

我已经可以发送和接收消息,但在接收方需要帮助.

我的网络应用程序应该如何持续监听一个队列来接收消息?

新邮件到达,服务器应该对它们进行操作.例如:将数据添加到数据库或发回消息.

我已经可以发送消息了.这是代码.

ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("clientQueue");
MessageProducer publisher = session.createProducer(queue);
connection.start();

Message message = null;
message = session.createTextMessage("Text Message");
publisher.send(message);
Run Code Online (Sandbox Code Playgroud)

我可以在请求后收到消息(点击;-))

connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
destination = session.createQueue("serverQueue");
consumer = session.createConsumer(destination);

while (true) {
    Message message = consumer.receive(300000);
    //Do message stuff
}
Run Code Online (Sandbox Code Playgroud)

我应该如何让Web应用程序连续监听队列? 建议的方式是什么?

热烈欢迎所有帮助.谢谢.

编辑 - 解决方案

目前的工作解决方案与DaveH的提议

我添加了一个ServletContextListener来连续收听我的消息.

web.xml中

<listener>
    <listener-class>com.test.JMSContextListener</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)

听众:

public class JMSContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        Thread thread = new Thread(new JMSConnector());
        thread.start();
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        //Nothing
    }
}
Run Code Online (Sandbox Code Playgroud)

连接:

public class JMSConnector implements Runnable {
    public void run() {
        try {
            Context context = new InitialContext();
            QueueConnectionFactory factory = (QueueConnectionFactory) context.lookup("java:comp/env/jms/ConnectionFactory");            
            Connection connection = factory.createConnection();
            Queue queue = (javax.jms.Queue) context.lookup("java:comp/env/jms/serverQueue");
            Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

            MessageConsumer consumer = session.createConsumer(queue);

            //This MessageListener will do stuff with the message
            MessageListenerImpl messageListener = new MessageListenerImpl();
            consumer.setMessageListener(messageListener);
            connection.start();

            // Start connection or nothing will happen!!!
            connection.start();
        } catch (JMSException ex) {
            //TODO
        } catch (NamingException ex) {
            //TODO
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一种建议的方式还是应该改进?

热烈欢迎所有帮助.谢谢.

Dav*_*veH 5

如果您的代码已经可以使用队列中的消息(看起来您确实这样做了),那么我认为您的问题归结为如何让那段代码运行。

看来您没有使用任何框架,所以我认为我将采用的方法是采用可以从队列中检索消息的代码并在应用程序服务器的单独线程中运行它。让该线程在应用服务器启动时启动,并在应用服务器关闭时自行整理。

在应用服务器启动时启动线程的最简单方法是引入一个 ServletContextListener(这里是一个示例)。在 Context Listener 中,在单独的线程中启动您的队列侦听代码。

编辑:我使用了这个建议的解决方案并将上面的代码添加到问题中。