9.4 在web中使用ActiveMQ消息
http://localhost:8161/demo/message/STOCKS/JAVA?type=topic
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.
?
9.4.2 Using the ActiveMQ Ajax API
9.4.2 使用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.
前文已经说,与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中进行配置.
?
<servlet>
<servlet-name>AjaxServlet</servlet-name>
<servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>
</servlet>
?
<servlet-mapping>
<servlet-name>AjaxServlet</servlet-name>
<url-pattern>/amq/*</url-pattern>
</servlet-mapping>
?
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.下面的代码片段完成了这两步配置:
?
<script type="text/javascript" src="amq/amq.js"></script>
<script type="text/javascript">amq.uri='/amq';</script>
?
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.
?
ActiveMQ demo程序是本书一直使用的stock portfolio示例程序为能在web环境中运行而修改后的版本.
这个例子包含一个用于发布市场数据的servlet和一个使用Ajax API处理市场数据的web页面.通过使用这个
例子,我们可以了解如何通过Ajax API处理消息.下面让我们看下下面的示例代码:
?
Listing 9.18 Consume messages from JavaScript using Ajax API
代码清单9.18 JavaScript 使用 Ajax API处理消息
?
var priceHandler =
{
_price:?
function(message)
{
if (message != null)?
{
var price = parseFloat(message.getAttribute('bid'))
var symbol = message.getAttribute('stock')
var movement = message.getAttribute('movement')
if (movement == null)?
{
movement = 'up'
}
?
var row = document.getElementById(symbol)
?
if (row)
{
// perform portfolio calculations
var value = asFloat(find(row, 'amount')) * price
var pl = value - asFloat(find(row, 'cost'))
// now let’s update the HTML DOM
find(row, 'price').innerHTML = fixedDigits(price, 2)
find(row, 'value').innerHTML = fixedDigits(value, 2)
find(row, 'pl').innerHTML = fixedDigits(pl, 2)
find(row, 'price').className = movement
find(row, 'pl').className = pl >= 0 ? 'up' : 'down'
}
}
}
};
?
function portfolioPoll(first)
{
if (first)
{
amq.addListener('stocks', 'topic://STOCKS.*', priceHandler._price);
}
}
?
amq.addPollHandler(portfolioPoll);
?
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 程序可以将动态页面技术提升至一个
新的高度.
?
?
?