编写一个与 JMS (ActiveMQ) 对话的 Servlet 和 OnMessage 更新站点
-
09-06-2019 - |
题
我正在构建一个站点,该站点使用简单的 AJAX Servlet 来与 JMS (ActiveMQ) 进行对话,并在消息从主题到达时更新站点。
我有 Javascript 为数据创建 XMLHttpRequest。Servlet 处理 Get 请求并发回 JSON。但是我不知道如何将我的 Servlet 连接到我的 ActiveMQ 消息代理中。它现在只是发回虚拟数据。
我认为Servelt应该实现消息监听器。然后onMessage发送数据到JavaScript页面。但我不知道该怎么做。
解决方案
让 servlet 实现 MessageListener 的问题是 servlet 是同步的,而 MessageListener 是异步的。相反,您应该创建一些其他对象来充当 MessageListener,并在消息传入时更新某处的某些状态(可能是数据库、JMX MBean 或有状态会话 EJB)。然后,servlet 可以查询该状态以查看是否有数据要报告给客户端,并且您的网页可以定期 ping servlet 以请求新数据。
其他提示
正如詹姆斯·斯特拉坎所说—— http://activemq.apache.org/ajax.html 是解决您的问题的理想的开箱即用解决方案。
如果您仍然想手动创建此类解决方案,您只需在 Ajax servlet 中创建 JMS 连接(每个请求的连接)。由于这个原因,请考虑使用 Spring JMS 模板( http://static.springsource.org/spring/docs/2.5.x/reference/jms.html )。然后只需在Servlet doGet/doPost 方法中接收消息即可。在这种情况下,请考虑较低的接收超时值。这种解决方案适用于队列和持久主题。
对于非持久主题,请考虑外部消息侦听器。春天 MessageListenerContainer
是实现此目的的绝佳工具:
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer
<property name="connectionFactory" ref="jmsFactory"/>
<property name="destination" ref="myTopic" />
<property name="messageListener" ref="lastTenUpdatesCache" />
</bean>
豆 lastTenUpdatesCache
将是一个单例 bean 实现 MesssageListener
. 。该 bean 将负责缓存最后十条消息(只需将其放入 java.util 列表中)。它将被注入到您的 Ajax servlet 中,因此在您的 doGet/doPost 方法中您可以询问它有关发送到该主题的最后 10 条消息的信息。
您是否尝试过阅读以下问题的答案 这个问题 其中链接到 ActiveMQ Ajax 支持. 。基本上,ActiveMQ 具有对 Ajax 的本机支持,因此您可以使用其 JavaScript 库直接订阅 ActiveMQ 主题。
另请参阅 ActiveMQ Web 示例 展示了如何使用 Ajax 和 ActiveMQ 进行实时聊天或实时股票投资组合屏幕等操作
您可能需要从 JNDI 获取 JMS 连接,如下所示:
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.setProperty(Context.PROVIDER_URL,
"tcp://hostname:61616");
javax.naming.Context ctx = new InitialContext(props);
// lookup the connection factory
javax.jms.TopicConnectionFactory factory =
(javax.jms.TopicConnectionFactory)ctx.lookup("ConnectionFactory");
// create a new TopicConnection for pub/sub messaging
javax.jms.TopicConnection conn = factory.getTopicConnection();
// lookup an existing topic
javax.jms.Topic mytopic = (javax.jms.Topic)ctx.lookup("MyTopic");
// create a new TopicSession for the client
javax.jms.TopicSession session =
conn.createTopicSession(false,TopicSession.AUTO_ACKNOWLEDGE);
// create a new subscriber to receive messages
javax.jms.TopicSubscriber subscriber = session.createSubscriber(mytopic);