ActiveMQ Ajax研究

来源:互联网 发布:tensorflow lite 编辑:程序博客网 时间:2024/05/01 09:52

Web中实现服务器推送的技术是很多的,比如Comet等等,开发框架也很多。能和消息中间件结合起来的有ActiveMQ、Kaazing等,我最终选择了ActiveMQ,因为它的支持是在是太广了,从C、C++到Java、C#,甚至Ajax、REST风格的接口,是我所喜欢的“万金油”类型。

学习了ActiveMQ官方的例子,自己也尝试了一下,下面是贴一些代码,比官方的例子要简单得多。

这是web.xml,配置了ActiveMQ的AjaxServlet,连接的是本机启动ActiveMQ的服务地址tcp://localhost:61616(ActiveMQ默认的)

<?xml version="1.0" encoding="UTF-8"?>
<web-app …>
    <context-param>
        <param-name>org.apache.activemq.brokerURL</param-name>
        <param-value>tcp://localhost:61616</param-value>
        <description>The URL of the Message Broker to connect to</description>
    </context-param>
    <servlet>
        <servlet-name>AjaxServlet</servlet-name>
        <servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>AjaxServlet</servlet-name>
        <url-pattern>/amq/*</url-pattern>
    </servlet-mapping>
</web-app>

然后是页面:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script type="text/javascript" src="amq/amq.js"></script>
        <script type="text/javascript">amq.uri='amq';</script>
        <script type="text/javascript" src="jquery/jquery-1.4.2.js"></script>
        <script type="text/javascript">
            function listener(message) {
                jQuery("#receive").append("<p>" + message.nodeType + "." + message.nodeValue + "</p>");
            };
            function pollHandler(first) {
                if (first) {
                    amq.addListener("test", "topic://test", listener);
                }
            };
            jQuery(function(){
                jQuery("#send").click(function(){
                    amq.sendMessage("topic://test", "[/"Hello/", /"Hello/"]");
                });
                jQuery("#clear").click(function(){
                    jQuery("#receive").html("");
                });
                amq.addPollHandler(pollHandler);
            })
        </script>
    </head>
    <body>
        <button id="send">发送</button>
        <button id="clear">清理</button>
        <div id="receive"></div>
    </body>
</html>

“发送”按钮发送消息到主题topic://test,接收到的消息直接填到div中。

同时我也写了一个Java程序来发送和接收消息,只贴发送消息的代码:

private static Destination destination;
private static String user = ActiveMQConnection.DEFAULT_USER;
private static String password = ActiveMQConnection.DEFAULT_PASSWORD;
private static String url = "tcp://localhost:61616";
private static String subject = "test";

public static void main(String[] args) {
    Connection connection = null;
    try {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);
        connection = connectionFactory.createConnection();
        connection.start();

        // Create the session
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = session.createTopic(subject);

        // Create the producer.
        MessageProducer producer = session.createProducer(destination);

        // Start sending messages
        producer.send(session.createTextMessage("<message>Hello</message>[/"Hello/", /"Hello/"]"));

    } catch (Exception e) {
        System.out.println("Caught: " + e);
        e.printStackTrace(System.out);
    } finally {
        try {
            connection.close();
        } catch (Throwable ignore) {
        }
    }
}

使用Firefox+Firebug设置断点跟踪研究,通过Ajax发送的消息统统是纯文本的,Java程序发送的文本内容Ajax同样能够接收到,而Ajax发送的消息Java程序也能接收到,类型为TextMessage,但是Ajax中接收的消息比较要命,我倒腾了半天才发现其中的诀窍。
ActiveMQ Ajax是通过HTTP长连接接收消息的,接收到的原始消息格式大概是下面的样子:

<ajax-response>
    <response id="test" destination="topic://test">消息内容</response>
</ajax-response>

id就是amq.addListener函数的第一个参数,标志Listener的,destination就是消息主题,这些都没问题,最要命的是ActiveMQ自动把消息内容解释成了DOM格式,也就是说Listener回调函数中的message参数是DOM结构的,如果是XML,那就得按照DOM的Element类型来解析,如果不是XML,那就是Text类型的,更有意思的是如果像这样一个消息:“<message>aaa</message><message>bbb</message>”,那么Listener回调函数会执行两次,因为里面包含了两个Element,如果是这样的消息:“<message>aaa</message>asdfasdfaksd”, Listener回调函数也会执行两次,““<message>aaa</message>”是Element,而“asdfasdfaksd”是Text,呵呵。

这就更加坚定了我使用Json的决心,解析由我自己做,省得和ActiveMQ撤不清。

参考:
http://activemq.apache.org/ajax.html
http://www.w3.org/TR/DOM-Level-3-Core/core.html

原创粉丝点击