在我以前的文章中,我介绍了几个有趣的用例,这些用例使用著名的消息代理HornetQ和ActiveMQ通过Websockects实现STOMP消息传递。 但是我没有介绍的是Apollo,因为我个人认为它的API是冗长的,并且不像Java开发人员那样表现力强。 尽管如此,我花更多的时间在Apollo上玩耍,就更加确信我已经拥有了很大的潜力。 所以这篇文章全是关于阿波罗的 。
我们正在尝试解决的问题保持不变:简单的发布/订阅解决方案,其中JavaScript Web客户端发送消息并侦听特定主题。 每当收到任何消息时,客户端都会显示警报窗口(请注意,我们需要使用支持Websockets的现代浏览器,例如Google Chrome或Mozilla Firefox )。
让我们从index.html (导入了很棒的stomp.js JavaScript库)开始着手吧 :
<script src="stomp.js"></script><script type="text/javascript">var client = Stomp.client( "ws://localhost:61614/stomp", "v11.stomp" );client.connect( "", "",function() {client.subscribe("/topic/test",function( message ) {alert( message );}, { priority: 9 } );client.send("/topic/test", { priority: 9 }, "Pub/Sub over STOMP!");});
</script>
客户端部分没有什么不同,只是主题名称现在为/ topic / test 。 但是服务器端相差很多。 Apollo是用Scala编写的,并包含异步,非阻塞编程模型。 我认为,这是一件非常好的事情。 虽然它带来了一个新的编程范式,但也不一定是一件坏事。 AppConfig类是用于配置嵌入式Apollo代理的类:
package com.example.messaging;import java.io.File;import org.apache.activemq.apollo.broker.Broker;
import org.apache.activemq.apollo.broker.jmx.dto.JmxDTO;
import org.apache.activemq.apollo.dto.AcceptingConnectorDTO;
import org.apache.activemq.apollo.dto.BrokerDTO;
import org.apache.activemq.apollo.dto.TopicDTO;
import org.apache.activemq.apollo.dto.VirtualHostDTO;
import org.apache.activemq.apollo.dto.WebAdminDTO;
import org.apache.activemq.apollo.stomp.dto.StompDTO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic Broker broker() throws Exception {final Broker broker = new Broker();// Configure STOMP over WebSockects connectorfinal AcceptingConnectorDTO ws = new AcceptingConnectorDTO();ws.id = "ws";ws.bind = "ws://localhost:61614"; ws.protocols.add( new StompDTO() );// Create a topic with name 'test'final TopicDTO topic = new TopicDTO();topic.id = "test";// Create virtual host (based on localhost)final VirtualHostDTO host = new VirtualHostDTO();host.id = "localhost"; host.topics.add( topic );host.host_names.add( "localhost" );host.host_names.add( "127.0.0.1" );host.auto_create_destinations = false;// Create a web admin UI (REST) accessible at: http://localhost:61680/api/index.html#!/ final WebAdminDTO webadmin = new WebAdminDTO();webadmin.bind = "http://localhost:61680";// Create JMX instrumentation final JmxDTO jmxService = new JmxDTO();jmxService.enabled = true;// Finally, glue all together inside broker configurationfinal BrokerDTO config = new BrokerDTO();config.connectors.add( ws );config.virtual_hosts.add( host );config.web_admins.add( webadmin );config.services.add( jmxService );broker.setConfig( config );broker.setTmp( new File( System.getProperty( "java.io.tmpdir" ) ) );broker.start( new Runnable() { @Overridepublic void run() { System.out.println("The broker has been started started.");}} );return broker;}
}
我想很清楚我的意思是冗长,不够表达,但至少很容易理解。 首先,我们在ws:// localhost:61614创建Websockects连接器,并要求它支持STOMP协议。 然后,我们使用名称测试创建一个简单的主题(在客户端将其称为/ topic / test )。 下一个重要步骤是创建虚拟主机,并将主题(和队列(如果有)绑定到该主机 )。 主机名列表非常重要,因为目标解析逻辑在很大程度上依赖它。 在接下来的步骤中,我们将配置Web管理员 UI和JMX工具 ,使我们能够访问配置,统计信息和监视。 要进行检查,请在Apollo代理启动后在Web浏览器中打开此URL 。 最后,通过应用配置并启动代理,我们一切顺利! 如您所见,异步编程模型会导致回调和匿名函数( Java 8在哪里?)。
现在,完成配置后,该看一下放置在Starter类中的启动逻辑了(同样,回调和匿名函数用于执行正常的关闭逻辑):
package com.example.messaging;import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;import org.apache.activemq.apollo.broker.Broker;
import org.springframework.context.annotation.ConfigurableApplicationContext;public class Starter {public static void main( String[] args ) throws Exception {try( ConfigurableApplicationContext context = new AnnotationConfigApplicationContext( AppConfig.class ) ) {final Broker broker = context.getBean( Broker.class ); System.out.println( "Press any key to terminate ..." );System.in.read(); final CountDownLatch latch = new CountDownLatch( 1 );broker.stop( new Runnable() { @Overridepublic void run() { System.out.println("The broker has been stopped.");latch.countDown();}} );// Gracefully stop the brokerif( !latch.await( 1, TimeUnit.SECONDS ) ) {System.out.println("The broker hasn't been stopped, exiting anyway ...");}}}
}
与前面的示例一样 ,在运行Starter类并在浏览器中打开index.html之后,我们应该看到类似以下内容:
很好,效果很好! 我非常确定,只是在Scala中重写代码,此Apollo API使用示例将看起来更加紧凑和简洁。 无论如何,如果您正在寻找杰出的消息传递体系结构,我认为Apollo消息代理绝对值得考虑。
所有资源均可在GitHub: Apollo示例上获得 。
翻译自: https://www.javacodegeeks.com/2013/09/easy-messaging-with-stomp-over-websockets-using-apollo.html