1、服务器推技术
通过客户端发出请求获取服务器端数据的方式通常称为“拉”技术,很形象说明客户端在拉取服务器端数据,而有时候需要服务器端主动向客户端“推”数据,比如监测聊天上线人数主动向上线发送消息,后台数据库发生变化是主动更新所有客户端展示。
2、Reverse Ajax实现服务器推技术
DWR2.x的推技术也叫DWR Reverse Ajax(逆向Ajax)主要是在BS架构中,从服务器端向多个浏览器主动推数据的一种技术。DWR的逆向Ajax主要包括两种模式:主动模式和被动模式。其中主动模式包括polling和comet两种,被动模式只有piggyback这一种。
(1)piggyback方式,是默认的方式。
如果后台有什么内容需要推送到前台,是要等到那个页面进行下一次ajax请求的时候,将需要推送的内容附加在该次请求之后,传回到页面。只有等到下次请求页面主动发起了,中间的变化内容才传递回页面。
(2)comet方式
当服务端建立和浏览器的连接,将页面内容发送到浏览器之后,对应的连接并不关闭,只是暂时挂起。如果后面有什么新的内容需要推送到客户端的时候直接通过前面挂起的连接再次传送数据。服务器所能提供的连接数目是一定的,在大量的挂起的连接没有关闭的情况下,可能造成新的连接请求不能接入,从而影响到服务质量。
(3)polling方式
由浏览器定时向服务端发送ajax请求,询问后台是否有什么内容需要推送,有的话就会由服务端返回推送内容。这种方式和我们直接在页面通过定时器发送ajax请求,然后查询后台是否有变化内容的实现是类似的。只不过用了dwr之后这部分工作由框架帮我们完成了。
3、配置web.xml使用reverse ajax
(1)piggyback方式,默认的dwr在web.xml文件的配置即piggyback方式。
(2)comet需要增加如下配置
<init-param>
<param-name>pollAndCometEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
(3)polling方式:在comet方式的基础之上,再配置以下参数
<init-param>
<param-name>org.directwebremoting.extend.ServerLoadMonitor</param-nam
<param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value>
</init-param>
<!-- 毫秒数。页面默认的请求间隔时间是5秒 -->
<init-param>
<param-name>disconnectedTime</param-name>
<param-value>60000</param-value>
</init-param>
4、编写聊天消息处理类
public class MessageManager {
private static List<String> msgList = new LinkedList<String>();
public List<String> getMsgList() {
return msgList;
}
public synchronized void sendMessage(String msg) {
msgList.add(msg);
showMessage();
}
private void showMessage() {
WebContext wctx = WebContextFactory.get();
String currentPage = wctx.getCurrentPage();
ScriptBuffer script = new ScriptBuffer(); script.appendScript("receiveMessages(").appendData(msgList).appendScript(");");// 调用页面的javascript方法把值添到页面上。
Collection pages = wctx.getScriptSessionsByPage(currentPage);// 循环出所有的会话页面并执行
for (Iterator it = pages.iterator(); it.hasNext();) {
ScriptSession otherSession = (ScriptSession) it.next();
otherSession.addScript(script);
}
}
}
5、dwr.xml中配置聊天消息处理类
<create creator="new" javascript="messageManager" scope="application">
<param name="class" value="service.MessageManager"/>
</create>
6、页面代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ReverseAjax.html</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type='text/javascript' src='/dwrtest/dwr/interface/messageManager.js'></script>
<script type='text/javascript' src='/dwrtest/dwr/engine.js'></script>
<script type='text/javascript' src='/dwrtest/dwr/util.js'></script>
<script type="text/javascript">
dwr.engine.setActiveReverseAjax(true);
function receiveMessages(msg) {
var message="";
for(var i=0;i<msg.length;i++)
message+=msg[i]+"<br>";
$("content").innerHTML=message
}
function init(){
messageManager.getMsgList(callback);
function callback(msg){
var message="";
for(var i=0;i<msg.length;i++)
message+=msg[i]+"<br>";
$("content").innerHTML=message
}
}
window.οnlοad=init;
</script>
</head>
<body >
<input type="text" id="txt"/>
<button onclick="messageManager.sendMessage($('txt').value)">send</button>
<div id="content"></div>
</body>
</html>
7、效果
在一个浏览器中发送消息,另外一个里面自动获取刚才的消息并显示。