当前位置: 首页 > ActiveMQ in Action 读书笔记 > 正文

9.4 在web中使用 ActiveMQ 消息

9.4 Messaging on the web with ActiveMQ

In the last few years we witnessed the rebirth of the web, usually called Web 2.0. The  transformation is taking place in two particular aspects of software development:     ? Service-oriented architecture  . SOA and web services play an increasingly important  role for many software projects. Users demand that software functionality be  exposed through some kind of web service interface. One way to achieve this is  to introduce RESTful principles to your application architecture, which allows  you to expose your application resources over HTTP. ActiveMQ follows these  principles by exposing its resources through its REST API, as we’ll see in a  moment.

9.4 在web中使用ActiveMQ消息

过去几年中,我们见证了web的重生,这里的web通常指Web2.0. 软件开发的在以下面向服务的架构  两个方面正在发生变化:SOA和web service 在许多软件工程中扮演着越来越重要的角色.用户要求软件的功能需要  通过一种web service接口的方式暴露出来.实现这种暴露的一种方式是在软件架构中使用REST 原则,该原则  允许你通过HTTP协议暴露系统资源.ActiveMQ遵循了这些原则,可以通过提供的REST API来暴露资源,正如我们  接下来要看到的那样.

It’s easy to say that Asynchronous JavaScript and XML (Ajax) revolutionized web  development as we knew it. The possibility of achieving asynchronous communication  between the browser and the server (without page reloading) opened  many doors for web developers, and provided a way for web applications to  become much more interactive. Naturally, you can use ActiveMQ Ajax API to  communicate directly with the broker from your web browser, which adds even  more asynchronous communication possibilities between clients (JavaScript  browser code) and servers (back-end server applications).

我们知道,异步JavaScript和XML(Ajax)为web开发带来了革命性改变.浏览器和服务器之间的  异步通信(不需要刷新页面)机制为web开发者提供了更多的开发方法,同时也为用户和web程序  之间提供了更好的交互.当然,你可以使用ActiveMQ Ajax API通过浏览器与代理直接通信,这样  给客户端(浏览器里的JavaScript代码)和服务器(应用程序服务器后台)段提供了更多异步交互  的可能性.

So with REST and Ajax APIs in its toolbox, ActiveMQ is well suited to be a good player in  the web arena. Using asynchronous messaging with standard web tools provides whole  new programming concepts to web developers. In the rest of this section we’ll explore  REST and Ajax APIs. We’ll see how you can send and receive messages from the command  line by issuing GET and POST HTTP calls. We’ll also describe the Ajax stock portfolio consumer  that comes with the ActiveMQ distribution, which shows how asynchronous messaging  and Ajax can be used together to provide real-time updates in web pages.

ActiveMQ的工具箱中拥有REST 和 Ajax API之后,ActiveMQ将更加适合web领域的开发.ActiveMQ的异步消息系统  使用标准的web开发工具为web开发者提供了全新的编程理念.本节内容中,我们将探寻ActiveMQ的REST 和 Ajax API.  我们将看到如何在命令行中使用GET和POST这样的HTTP请求发送和接受消息.我们还会展示基于Ajax的stock portfolio  消息消费者,这也展示了如何整合异步消息和Ajax来实现web页面中实时的数据更新.

9.4.1 Using the ActiveMQ REST API

As you probably know, the term REST first appeared in Roy T. Fielding’s PhD thesis  Architectural Styles and the Design of Network-based Software Architectures (http://mng.bz/  2Xa4). In this work, Fielding explains a collection of network architecture principles  that define how to address and manage resources (in general) over the network. In  simpler terms, if an application implements a RESTful architecture, it usually means  that it exposes its resources using HTTP protocol and in a similar philosophy to those  used on the World Wide Web.

9.4.1 使用ActiveMQ REST API

你也许知道, 术语REST首次出现在Roy T. Fielding的博士论文<架构风格和基于网络的软件架构设计>  (http://mng.bz/2Xa4).在这篇论文中,Fielding阐述了一系列的网络架构原则用来定义如何定位和管理  (通常指)网络上的资源.简单的说,如果一一个程序实现了RESTful结构,通常意味着这个程序暴露了其  系统资源,使用HTTP协议或类似方式可以通过互联网访问这些资源.

The web is designed as a system for accessing documents over the internet. Every  resource on the web (HTML page, image, video, and so forth) has a unique address  defined by its URL (uniform resource locator). Resources are mutually interlinked  and transferred between clients and servers using the HTTP protocol. The HTTP GET  method is used to obtain the representation of the resource, and shouldn’t be used to  make any modifications to it. The POST method, on the other hand, is used to send  data to be processed by the server. Apply these principles to your application’s  resources (destinations and messages in case of a JMS broker), and you’ve defined a  RESTful API. Now let’s see how ActiveMQ implements its REST API and how you can  use it to send and receive messages from the broker. Figure 9.2 shows how you can  connect a Java producer (sending messages using the OpenWire protocol) with  almost any consumer that can use standard HTTP connections.

web是一个被设计成在互联网上访问文档的系统.web中的每一个资源(HTML页面,图片,视频等)都有一个  唯一的通过其URL(统一资源定位器)定义的地址.每个资源通过HTTP协议实现在客户端和服务器之间的互  联和传输.HTTP协议中的GET方法用来获取资源,但不能对原始资源做任何修改.POST方法用于发送需要由数据  服务器处理的数据.一旦将这些方法应用到你程序中的资源(比如对于JMS来说是消息目的地和消息)上,你就已经  实现了RESTful API.现在,让我们看看ActiveMQ是如何实现REST API的,以及我们如何使用REST API以便  通过代理发送和接收消息.图9.2展示了任意的消息消费者如何使用标准的HTTP协议连接到Java 消息生产者  (使用OpenWire协议发送消息).

ActiveMQ comes with an embedded web server that starts at the same time your broker  starts. This web server is used to provide all necessary web infrastructure for the  ActiveMQ broker, including the REST API. By default, the demo application is started at  http://localhost:8161/demo and it’s also configured to expose the REST API at the   following URL: http://localhost:8161/demo/message

ActiveMQ自带一个内嵌的web服务器,并且当启动ActiveMQ代理的时候这个web服务器也会一起启动.  这个web服务器用于为ActiveMQ提供所有必要的web功能,包括提了REST API的实现.默认情况下,代理  启动时一起启动的demo程序可以通过http://localhost:8161/demo访问,并且可以通过配置,将接收  REST API访问的URL设置为:http://localhost:8161/demo/message.

The API is implemented by the org.apache.activemq.web.MessageServlet servlet, and  if you wish to configure an arbitrary servlet container to expose the ActiveMQ REST  API, you have to define and map this servlet in an appropriate web.xml file (of course,  all necessary dependencies should be in your classpath). The following example  shows how to configure and map this servlet to the /message path as it is done in the  demo application:

ActiveMQ的REST API有org.apache.activemq.web.MessageServlet 这个servlet实现.如果你打算  在其他任意的servlet容器中配置以便暴露 ActiveMQ REST API的话,你需要在相应的web.xml中定义  servlet映射(当然,这个servlet的所有依赖都需要放到类路径(classpath)下).下面的配置例子来自demo  程序,展示了如何配置并映射这个servlet到/message路径下:

When configured like this, broker destinations are exposed as relative paths under the  defined URI. For example, the STOCKS.JAVA topic is mapped to the following URI:  http://localhost:8161/demo/message/STOCKS/JAVA?type=topic

通过这样的配置,代理的消息目的地就通过下面的RUI路径暴露出来.比如,STOCKS.JAVA消息主题就被映射到  下面的URI上:http://localhost:8161/demo/message/STOCKS/JAVA?type=topic

As you can see, a path translation is in place, so destination name path elements (separated  with .) are adjusted to the web URI philosophy where / is used as a separator.  Also, we used the type parameter to define whether we want to access a queue or a topic.

正如你看到的,路径的翻译需要根据相应规则来,因此消息目的地的名称中的的路径分割符(.)需要用URI中  的分隔符/来替代.

Now we can use GET and POST requests to receive and send messages to destinations  (retrospectively). We’ll run some simple examples to demonstrate how you can  use the REST API to communicate with your broker from the command line. For that  we’ll use two popular programs that can make HTTP GET and POST method requests  from the command line. First we’ll use GNU Wget (http://mng.bz/DMf6), a popular  tool for retrieving files using HTTP, to subscribe to the desired destination:

现在,我们可以使用GET和PSOT请求接收和发送消息到消息目的地了.我们将运行一些例子来说明如何  在命令里使用REST API来与代理进行通信.为此,我们将使用连个常用的程序,使用HTTP GET和POST方  法从命令行发送请求.首先,我们使用一个通过HTTP获取文件的流行工具GNU Wget(http://mng.bz/DMf6) 来订阅所需的消息目的地消息

With this command, we instructed wget to receive the next available message from the  STOCKS.JAVA topic and to save it to the message.txt file. You may also notice that we  keep the HTTP sessions alive between wget calls by saving and sending cookies back to  the server. This is important because the actual consumer API used by the Message-Servlet is stored in the session. So if you try to receive every message using a new session,  you’ll spawn a lot of consumers unnecessarily and your requests will probably be  left hanging. Also, if you plan to use multiple REST consumers, it’s advisable to set the  prefetch size to 1, just as we did with STOMP consumers. To do that, you have to set  the consumer.prefetchSize initialization parameter value of your message servlet.  The following example shows how to achieve that:

使用这个命令,我们展示了使用wget命令接收下一个来自STOCKS.JAVA 主题的消息,并将其存储到message.txt文件中.也许,你已经注意到了,我们通过将cookies发送给服务器来保持wget HTTP 连接的session是活动的. 这点和重要,因为Message-Servlet实际使用的消费者API是存储在session中的.因此,如果你打算使用新的session来接收每个消息,你需要生成大量的消费者,这个没有必要的,甚至会到导致请求挂起.同样,如果你打算使用多个REST消费者的话,将prefetch四则设置为1是明智的,这点跟处理STOMP消费者类似.为此,你需要在message servlet中设置consumer.prefetchSize参数的初始值.下面的例子显示了如何设置:

Now, it’s time to send some messages to our topic. For that we’ll use cUrl (http://curl.haxx.se/), a popular command-line tool for transferring files using the HTTP  POST method. Take a look at the following command:

现在是时候发送一些消息到主题了.我们将使用一个流行的命令行工具cUrl(http://curl.haxx.se/)通过使用HTTP的POST方法来传输文件.
请看下面的命令: 

Here we’ve used the -d switch to specify that we want to POST data to the server. As  you can see, the actual content of the message is passed as the body parameter. The sent message should be received by our previously run consumer.  This simple example shows how easy it is to use the REST API to do asynchronous messaging even from the command line. But generally, you should give STOMP a try  (if it’s available for your platform) before falling back to the REST API, because it  allows you more flexibility and is much more messaging-oriented. 

这里我们使用了-d开关来指示我们打算推送(POST)数据到服务器. 正如你所见,真正的消息内容是作为body参数传送的. 被发送的消息应该会被前面运行的消费者接收. 这个简单的实例向我们展示了即使是使用命令行,通过REST API来异步的发送消息也是相当容易的. 但是,通常,你应当在打算使用REST API之前先尝试STOMP(如果你的平台支持STOMP的话).因为STOMP具有更大的灵活性并且也是更加面向消息的.

9.4.2 Using the ActiveMQ Ajax API

As we said earlier, the option to communicate with the web server asynchronously  changed how developers thought about web applications. In this section we’ll see how  web developers can embrace asynchronous programming even further, by communicating  with message brokers directly from JavaScript.

9.4.2 使用ActiveMQ Ajax API

前文已经说,与web服务器之间异步通信改变了开发者对于web程序的想法.本小节里,我们将看到web  开放人员如何通过使用JavaScript直接和消息代理通信来更好的拥抱异步程序程序开发.

First of all, we should configure our web server to support the ActiveMQ Ajax API.  Similar to the MessageServlet class used for implementing the REST API, ActiveMQ  provides an AjaxServlet that implements Ajax support. Figure 9.3 shows how the  AjaxServlet serves as a mediator between the web browser and the broker. So the  JavaScript clients communicate with the servlet, which connects to the broker as a  standard JMS client.

首先,我们需要配置web服务器支持ActiveMQ Ajax API.与MessageServlet实现了REST API  类似,ActiveMQ使用AjaxServlet试下了对Ajax的支持.图9.3中展示了AjaxServlet做为web浏览器  和代理之间的中介,因而JavaScript客户端可以想一个标准的JMS客户端一样连接到代理,从而实现  与servlet通信.

The following example shows how to configure it in your web application’s WEBINF/   file:

下面的示例代码展示了如何在web程序的WEBINF/web.xml中进行配置.

Of course, in order to make it work properly you have to put ActiveMQ in your web  application’s classpath. Now that we have a server side configured and a servlet listening  to the requests submitted to the URIs starting with /amq/, we can proceed to  implementing the client side of our Ajax application.

当然,为了是配置能正常工作,你需要将ActiveMQ放到web程序的类路径(classpath)下.现在,我们配置好了  服务器端并使用一个servlet来监听来自URI中包含/amq/路径的请求.接下来我们可以实现客户端的Ajax程  序了.

First of all, we have to include the amq.js script, which includes all necessary  JavaScript libraries for us. Also, we have to point the amq.uri variable to the URI our  Ajax servlet listens to. The following snippet shows how to achieve this:

首先,我们需要引入amq.js脚本文件,该文件包含全部所需的JavaScript库.其次,我们还需要设置   amq.uri变量指向Ajax servlet监听的URI.下面的代码片段完成了这两步配置:

The amq.js script defines a JavaScript object named amq, which provides an API for us  to send messages and subscribe to ActiveMQ destinations. The following example  shows how to send a simple message from our Ajax application:  amq.sendMessage(“topic://TEST”, “message”);

amq.js定义了一个名称为amq的JavaScript对象,该对象为我们提供了发送消息以及订阅ActiveMQ  消息目的地的API.下面的的示例代码展示了如何通过Ajax程序发送一个简单消息:  amq.sendMessage(“topic://TEST”, “message”);

It can’t be much simpler than this: all you have to do is call a sendMessage() method  and provide a destination and the text of the message to be sent.

所有需要你做的就是调用sendMessage()方法并提供一个消息目的地和一个需要被发送的文本消息  ,没有比这个更简单的了.

If you wish to subscribe to a certain destination (or multiple destinations), you  have to register a callback function that will be called every time a new message is  available. This is done with the addListener() method of the amq object, which in  addition to a callback function accepts a destination to subscribe to and ID that makes  further handling of this listener possible.

如果你打算订阅某个特定的消息目的地(或多个消息目的地),你需要注册一个回调函数,当接收到一个  新消息时,会调用这个函数.尅通过 amq对象的addListener() 注册回调函数,该函数除了接受一个 回  调函数作为参数外,同时还接受一个订阅的消息目的和一个ID作为参数,使用该ID参数使得进一步处  理这个监听器成为可能.

The ActiveMQ demo application comes with the stock portfolio example we’ve  used throughout the book, adopted to the web environment. The example contains a  servlet that publishes market data and a web page that uses the Ajax API to consume  that data. Using this example, we’ll show how to consume messages using the Ajax  API. Let’s take a look at the code shown in the following listing.
Listing 9.18 Consume messages from JavaScript using Ajax API

ActiveMQ demo程序是本书一直使用的stock portfolio示例程序为能在web环境中运行而修改后的版本.  这个例子包含一个用于发布市场数据的servlet和一个使用Ajax API处理市场数据的web页面.通过使用这个  例子,我们可以了解如何通过Ajax API处理消息.下面让我们看下下面的示例代码:
代码清单9.18 JavaScript 使用 Ajax API处理消息

For starters, we’ve defined a JavaScript object named priceHandler with the _price()  function we’ll use to handle messages. This function finds an appropriate page element  and updates its value (or changes its class to show whether it’s a positive or negative  change). Now we have to register this function to listen to the stock topics. As you  can see, we’ve named our listener stocks, set it to listen to all topics in the STOCKS  name hierarchy, and defined _price() as a callback function. You can later remove  this subscription (if you wish) by calling the removeListener() function of the amq  object and providing the specified ID (stocks in this case).

首先,我们定义了一个名称为priceHandler的JavaScript对象,该对象含有一个_price()方法用于处理消息.该方法会查找一个合适的页面元素并更新该页面元素的值(或者改变其class样式以展示变化正向还是负向的).  闲我们已经将这个函数注册为监听stock提提了.正如你所看到的,我们将监听器命名为stocks,并将其设置为  监听所有以STOCKS开头的主题,同时定义_price()作为回调函数.你可以在稍后通过调用amq对象的   removeListener()方法传递一个制定的ID(本例中使用的ID是stocks)来移除这个器.

Now we’re ready to run this example. First we’re going to start the portfolio publisher  servlet by entering the following URL in the browser:  http://localhost:8161/demo/portfolioPublish?count=1&refresh=2&stocks=IBMW

&stocks=BEAS&stocks=MSFT&stocks=SUNW  The Ajax consumer example is located at the following address:  http://localhost:8161/demo/portfolio/portfolio.html

现在我们可以运行这个例子了.首先在浏览器地址栏输入
http://localhost:8161/demo/portfolioPublish?
count=1&refresh=2&stocks=IBMW&
stocks=BEAS&stocks=MSFT&stocks=SUNW
以便启动portfolio的publisher.Ajax 消费者例子的位置为下面的地址:  http://localhost:8161/demo/portfolio/portfolio.html

After starting it, you can expect a page that looks similar to the one shown in figure 9.4.  The page will dynamically update as messages come to the broker. This simple  example shows how Ajax applications can benefit from asynchronous messaging, thus  taking dynamic web pages to a whole new level.

启动后,你将看到一个页面看起来类似于图9.4所示.该页面会根据来自代理的消息动态更新.  从这个简单的例子可以看出,得利于异步消息系统,Ajax 程序可以将动态页面技术提升至一个新的高度.

打个赏呗

   微信打赏  支付宝打赏


本文固定链接: https://www.jack-yin.com/coding/translation/activemq-in-action/1604.html | 边城网事

该日志由 边城网事 于2013年11月21日发表在 ActiveMQ in Action 读书笔记 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 9.4 在web中使用 ActiveMQ 消息 | 边城网事

9.4 在web中使用 ActiveMQ 消息 暂无评论

发表评论

快捷键:Ctrl+Enter