一、ActiveMQ 实现多人聊天室
这是项目最终的目录结构:
项目源码:http://download.youkuaiyun.com/detail/u011983531/9238447
下面我们分四部分完成这个项目。
各部分的详细介绍,请参考下面的实现原理。
(1)导入需要的jar包,这些jar包可以在ActiveMQ的安装目录下的lib文件夹下找到,如下:
(2)导入需要的JS文件,这些JS文件可以在ActiveMQ安装目录下的webapp-demo/demo/js文件夹下面找到(这里的demo项目其实就是ActiveMQ官方给我们提供的例子),如下:
(3)配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>mqajax</display-name>
<context-param>
<description>Whether we should include an embedded broker or not</description>
<param-name>org.apache.activemq.brokerURL</param-name>
<param-value>tcp://127.0.0.1:61616</param-value>
</context-param>
<servlet>
<servlet-name>AjaxServlet</servlet-name>
<servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet>
<servlet-name>MessageServlet</servlet-name>
<servlet-class>org.apache.activemq.web.MessageServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>QueueBrowseServlet</servlet-name>
<servlet-class>org.apache.activemq.web.QueueBrowseServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>PortfolioPublishServlet</servlet-name>
<servlet-class>org.apache.activemq.web.PortfolioPublishServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AjaxServlet</servlet-name>
<url-pattern>/amq/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MessageServlet</servlet-name>
<url-pattern>/message/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>QueueBrowseServlet</servlet-name>
<url-pattern>/queueBrowse/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>PortfolioPublishServlet</servlet-name>
<url-pattern>/portfolioPublish</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
(4)实现聊天界面index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/amq_jquery_adapter.js"></script>
<script type="text/javascript" src="js/amq.js"></script>
<script type="text/javascript">
var amq = org.activemq.Amq;
amq.init({
uri: 'amq',
logging: true,
timeout: 1
});
var myHandler = function(message){
$("#msgDiv").append(message);
$("#msgDiv").append("<br>");
}
amq.addListener("smeguangdong","topic://FirstTopic",myHandler);
function send(){
var nickname = $("#nickname").val();
var content = $("#content").val();
var msg = nickname + " : " +content;
amq.sendMessage("topic://FirstTopic","<message>"+msg+"</message>");
}
</script>
</head>
<body>
<b>多人聊天室</b>
<hr>
<div style="height:300px;width:600px;border:block;overflow:auto" id="msgDiv">
</div>
昵称:<input type="text" id="nickname">
内容:<input type="text" id="content">
<button onclick="send()">发送</button>
</body>
</html>
将项目部署到Tomcat后,运行结果如下:
二、实现原理
1、web.xml的配置
web.xml配置,主要是配置接收客户端请求的servlet,即AjaxServlet。
<servlet>
<servlet-name>AjaxServlet</servlet-name>
<servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
< load-on-startup>1< /load-on-startup>表示这个servlet在tomcat启动时就实例化;< async-supported>true< /async-supported>表示这个Servlet允许异步加载。
另外,这个servlet是要连接到实际的代理的,所以web.xml还提供了一个参数,用来配置这个servlet要连接代理的URI,配置如下:
<context-param>
<description>Whether we should include an embedded broker or not</description>
<param-name>org.apache.activemq.brokerURL</param-name>
<param-value>tcp://127.0.0.1:61616</param-value>
</context-param>
表示启动时servlet将连接tcp://127.0.0.1:61616.
2、amq.js的使用
js与ActiveMQ交互的库文件amq.js,这个js文件还依赖一些基于公共JavaScript框架:jquery.js、amq_jquery_adapter.js。因此,使用amq.js时,,必须先引入jquery库文件和适配器库文件amq_jquery_adapter.js。
amq.js里面提供了sendMessage方法可以发送消息到代理,而addListener和removeListener方法可以给指定的的消息目的地添加或删除监听器,添加监听器后就可以接收消息了。
在web页面使用sendMessage发送消息,其实是向后台的一个servlet发送请求,然后由该servlet发送消息给代理。页面调用addListener注册监听器,其实也是发送请求给servlet,由servlet创建一个目的地的消费者,当该目的地有消息时,servlet处理消息,并将消息处理响应发送给客户端。因为采用web的BS架构,servlet不能直接将响应发送给客户端. 这里amq.js中其实是采用了一种页面轮询的方式向服务器请求消息,以便监听代理上指定的目的地。
详细信息参考ActiveMQ文档:http://activemq.apache.org/ajax.html