使用ActiveMQ和HornetQ通过WebSocket通过STOMP轻松进行消息传递
消息傳遞是用于構建不同級別的分布式軟件系統的極其強大的工具。 通常,至少在Java生態系統中,客戶端(前端)從不直接與消息代理(或交換)進行交互,而是通過調用服務器端(后端)服務來進行交互。 否則,客戶甚至可能不知道已安裝了消息傳遞解決方案。
隨著Websockets越來越被采用,對諸如STOMP (用于與消息代理或交換進行通信)之類的面向文本的協議的廣泛支持將產生影響。 今天的帖子將嘗試解釋公開兩個非常流行的JMS實現(Apache ActiveMQ和JBoss HornetQ)是多么簡單,這兩個Web前端(JavaScript)可以使用基于Websockets的 STOMP來用于Web前端(JavaScript)。
在深入研究代碼之前,可能有人認為這樣做不是一個好主意。 那目的是什么? 答案確實取決于:
- 您正在開發原型/概念證明,并且需要簡單的方法來集成發布/訂閱或對等消息傳遞
- 您不需要/不需要構建復雜的體系結構,而最簡單的解決方案就足夠了
可擴展性,故障轉移和許多其他非常重要的決定在這里沒有考慮,但是如果您正在開發健壯和有彈性的體系結構,則絕對應該考慮。
因此,讓我們開始吧。 與往常一樣,最好從我們要解決的問題開始:我們想開發一個簡單的發布/訂閱解決方案,使用JavaScript編寫的Web客戶端能夠發送消息并偵聽特定主題。 只要收到任何消息,客戶端就會顯示簡單的警報窗口。 請注意,我們需要使用支持Websocket的現代瀏覽器,例如Google Chrome或Mozilla Firefox 。
對于我們的兩個示例,客戶端的代碼均保持不變,因此我們從此開始。 最佳起點是STOMP Over WebSocket文章,其中介紹了stomp.js模塊,這是我們的index.html :
<script src="stomp.js"></script><script type="text/javascript">var client = Stomp.client( "ws://localhost:61614/stomp", "v11.stomp" );client.connect( "", "",function() {client.subscribe("jms.topic.test",function( message ) {alert( message );}, { priority: 9 } );client.send("jms.topic.test", { priority: 9 }, "Pub/Sub over STOMP!");});</script>非常簡單的代碼,但很少有細節值得解釋。 首先,我們正在ws:// localhost:61614 / stomp尋找Websockets端點。 這足以進行本地部署,但最好用真實IP地址或主機名替換localhost 。 其次,一旦連接,客戶端就訂閱該主題(僅對優先級為9的消息感興趣),并在此之后立即將消息發布到該主題。 從客戶的角度來看,我們已經完成了。
讓我們繼續進行消息代理,列表中的第一個是Apache ActiveMQ 。 為了簡化示例,我們將不使用配置XML文件將Apache ActiveMQ代理嵌入到簡單的Spring應用程序中。 由于源代碼在GitHub上可用 ,因此我將跳過POM文件片段,僅顯示代碼:
package com.example.messaging;import java.util.Collections;import org.apache.activemq.broker.BrokerService; import org.apache.activemq.broker.jmx.ManagementContext; import org.apache.activemq.command.ActiveMQDestination; import org.apache.activemq.command.ActiveMQTopic; import org.apache.activemq.hooks.SpringContextHook; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class AppConfig {@Bean( initMethod = "start", destroyMethod = "stop" )public BrokerService broker() throws Exception {final BrokerService broker = new BrokerService(); broker.addConnector( "ws://localhost:61614" ); broker.setPersistent( false );broker.setShutdownHooks( Collections.< Runnable >singletonList( new SpringContextHook() ) );final ActiveMQTopic topic = new ActiveMQTopic( "jms.topic.test" );broker.setDestinations( new ActiveMQDestination[] { topic } );final ManagementContext managementContext = new ManagementContext();managementContext.setCreateConnector( true );broker.setManagementContext( managementContext );return broker;} }如我們所見, ActiveMQ代理配置有ws:// localhost:61614連接器,該連接器假定使用STOMP協議。 另外,我們正在創建名稱為jms.topic.test的 JMS主題,并啟用JMX管理工具。 并運行它,簡單的Starter類:
package com.example.messaging;import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Starter {public static void main( String[] args ) {ApplicationContext context = new AnnotationConfigApplicationContext( AppConfig.class );} }現在,啟動并運行它,讓我們在瀏覽器中打開index.html文件,我們應該看到類似以下內容:
簡單! 對于好奇的讀者, ActiveMQ使用Jetty 7.6.7.v20120910來支持Websockets,并且不能與最新的Jetty發行版一起使用。
接下來,就HornetQ而言 ,實現看起來有些不同,盡管也不是很復雜。 由于Starter類保持不變,因此唯一的變化是配置:
package com.example.hornetq;import java.util.Collections; import java.util.HashMap; import java.util.Map;import org.hornetq.api.core.TransportConfiguration; import org.hornetq.core.config.impl.ConfigurationImpl; import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory; import org.hornetq.core.remoting.impl.netty.TransportConstants; import org.hornetq.core.server.JournalType; import org.hornetq.jms.server.config.ConnectionFactoryConfiguration; import org.hornetq.jms.server.config.JMSConfiguration; import org.hornetq.jms.server.config.TopicConfiguration; import org.hornetq.jms.server.config.impl.ConnectionFactoryConfigurationImpl; import org.hornetq.jms.server.config.impl.JMSConfigurationImpl; import org.hornetq.jms.server.config.impl.TopicConfigurationImpl; import org.hornetq.jms.server.embedded.EmbeddedJMS; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class AppConfig {@Bean( initMethod = "start", destroyMethod = "stop" )public EmbeddedJMS broker() throws Exception {final ConfigurationImpl configuration = new ConfigurationImpl();configuration.setPersistenceEnabled( false );configuration.setJournalType( JournalType.NIO );configuration.setJMXManagementEnabled( true );configuration.setSecurityEnabled( false );final Map< String, Object > params = new HashMap<>();params.put( TransportConstants.HOST_PROP_NAME, "localhost" );params.put( TransportConstants.PROTOCOL_PROP_NAME, "stomp_ws" );params.put( TransportConstants.PORT_PROP_NAME, "61614" );final TransportConfiguration stomp = new TransportConfiguration( NettyAcceptorFactory.class.getName(), params );configuration.getAcceptorConfigurations().add( stomp );configuration.getConnectorConfigurations().put( "stomp_ws", stomp );final ConnectionFactoryConfiguration cfConfig = new ConnectionFactoryConfigurationImpl( "cf", true, "/cf" );cfConfig.setConnectorNames( Collections.singletonList( "stomp_ws" ) );final JMSConfiguration jmsConfig = new JMSConfigurationImpl();jmsConfig.getConnectionFactoryConfigurations().add( cfConfig );final TopicConfiguration topicConfig = new TopicConfigurationImpl( "test", "/topic/test" );jmsConfig.getTopicConfigurations().add( topicConfig );final EmbeddedJMS jmsServer = new EmbeddedJMS();jmsServer.setConfiguration( configuration );jmsServer.setJmsConfiguration( jmsConfig );return jmsServer;} }完整的源代碼在GitHub上 。 在運行Starter類并在瀏覽器中打開index.html之后,我們應該看到非常相似的結果:
HornetQ配置看起來更加冗長,但是除了出色的Netty框架之外,沒有涉及其他依賴項。
出于好奇,我將ActiveMQ代理替換為Apollo實現。 盡管我成功實現了預期的功能,但我發現該API非常麻煩,至少在當前版本1.6中如此,因此本文中沒有涉及它。
翻譯自: https://www.javacodegeeks.com/2013/09/easy-messaging-with-stomp-over-websockets-using-activemq-and-hornetq.html
總結
以上是生活随笔為你收集整理的使用ActiveMQ和HornetQ通过WebSocket通过STOMP轻松进行消息传递的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Mockito和BeanPostPr
- 下一篇: apple电脑验机百度经验(苹果验机电脑