刚才写了一篇《dwr传对象到前台》,现在继续下一个总结点,dwr又一个令人兴奋的技术后台服务器推送技术,需要的包我就不写了
web.xml配置
<servlet>
<display-name>DWR Servlet</display-name>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<!-- 用于调试 -->
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!-- 设置服务器可以向前天推送数据 -->
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!-- 设置推动的模式为轮询模式-->
<param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>
<param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value>
</init-param>
<init-param>
<!--轮询的时间为1秒一次,根据需要更改时间-->
<param-name>disconnectedTime</param-name>
<param-value>1000</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
dwr.xml
<create creator="new" javascript="DataPollService">
<param name="class" value="com.dwr.service.DataPollService"/>
</create>
java代码
user类
package com.dwr.model;
public class User {
int id ;
String name ;
int number ;
public User(){}
public User(int id, String name, int number) {
super();
this.id = id;
this.name = name;
this.number = number;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "id="+id+" name="+name+" number="+number;
}
}
DataPollService 类
package com.dwr.service;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;
import org.directwebremoting.WebContextFactory;
import com.dwr.model.User;
public class DataPollService {
ServletContext context = null ;
ScriptSession scriptSession = null ;
//----给所有的页面推数据,通过Brower.withAllSessions,适合全部页面--------------------------
public DataPollService(){
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
HttpSession session = request.getSession();
//初始化工作,目的是用一个服务器级的容器来装scriptsession,便于跨浏览器操作
context = session.getServletContext();
}
@SuppressWarnings("unchecked")
public void initScriptSession(){
System.out.println("into initScriptSession!");
//创建一个session,只要页面调用这个方法
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
// scriptSession.setAttribute("allpages", scriptSession);
//拿到放在scriptSessions中的scriptsession
List<ScriptSession> scriptSessions = (List<ScriptSession>) context.getAttribute("scriptSessions" );
if(scriptSessions == null){
scriptSessions = new ArrayList<ScriptSession>() ;
}
//添加一个新的scriptsession
scriptSessions.add(scriptSession);
context.setAttribute("scriptSessions", scriptSessions);
}
@SuppressWarnings("unchecked")
public void pollDataToAllPage(){
System.out.println("into pollDataToCpage!");
//拿出所有的session
final List<ScriptSession> scriptSessions = (List<ScriptSession>) context.getAttribute("scriptSessions" );
if (scriptSessions ==null) {
return ;
}
System.out.println("scriptSessions.size()="+scriptSessions.size());
Browser.withAllSessions(new Runnable() {
@Override
public void run() {
//掉用浏览器客户端的js函数,实现推送数据
System.out.println("run");
ScriptBuffer scriptBuffer = new ScriptBuffer();
// 只要有页面有这个js函数,即可以推送
scriptBuffer.appendScript("polledDataByServer(") .appendData( new User(1,"张三",1)).appendScript(");");
for(ScriptSession scriptSession :scriptSessions){
//推送数据
scriptSession.addScript(scriptBuffer);
}
}
});
}
//-------------------------------给D页面推数据,通过Brower.withSession,通过sessionId来定位,适合指定页面-------------
//创建一个sessionId属于D页面的
public void createSessionId(){
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
// scriptSession.setAttribute("", arg1);
// sessionIdString = scriptSession.getId();
//通过sessionid来定位
context.setAttribute("sessionId", scriptSession.getId());
context.setAttribute("scriptSession", scriptSession);
System.out.println("into createSessionId! sessonId= "+scriptSession.getId());
}
public void pollDataToSpePage(){
//执行和操作的scriptSessionId 必须是由createSessionId创建的session所产生,因此需要在创建session的时候,将scriptsesson保留在context里面
final ScriptSession scriptSession = (ScriptSession) context.getAttribute("scriptSession");
String sesssionId = (String) context.getAttribute("sessionId");
System.out.println("into pollDataToSpePage sessionId="+sesssionId +" scriptSession="+scriptSession);
Browser.withSession(sesssionId, new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("run");
ScriptBuffer scriptBuffer = new ScriptBuffer();
// 只要有页面有这个js函数,即可以推送
scriptBuffer.appendScript("polledDataToOneByServer(") .appendData( new User(1,"张三",1)).appendScript(");");
//推送数据,
scriptSession.addScript(scriptBuffer);
}
});
}
}
jsp代码
A.jsp代码,用来触发动作传到服务器,服务器根据需要推送数据给需要的页面,可以群发,也可以指定页面发,具体上上面的java代码
<!-- 注意script的顺序,engine.js 需要放在最前面 -->
<script src='<%=request.getContextPath() %>/dwr/engine.js'></script>
<script src='<%=request.getContextPath() %>/dwr/util.js'></script>
<script src='<%=request.getContextPath() %>/dwr/interface/DataPollService.js'></script>
<script type="text/javascript">
function clickMe(){
//alert()
dwr.engine.setActiveReverseAjax(true);
DataPollService.pollDataToAllPage();
}
function clickMe1(){
// alert()
dwr.engine.setActiveReverseAjax(true);
DataPollService.pollDataToSpePage();
}
</script>
<title>A页面</title>
</head>
<body>
<input type="button" value="请求服务器推送数据给所有的页面" onclick="clickMe()">
<input type="button" value="请求服务器推送数据给D页面" onclick="clickMe1()">
</body>
</html>
B.jsp 页面代码
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<!-- 注意script的顺序,engine.js 需要放在最前面 -->
<script src='<%=request.getContextPath() %>/dwr/engine.js'></script>
<script src='<%=request.getContextPath() %>/dwr/util.js'></script>
<script src='<%=request.getContextPath() %>/dwr/interface/DataPollService.js'></script>
<script type="text/javascript">
window.onload=function(){
//将后台推送数据给前台设置为true
dwr.engine.setActiveReverseAjax(true);
//创建一个属于这个页面的scriptSession
DataPollService.initScriptSession();
};
//等待服务器的数据推送,data是服务器推过来的数据,不仅仅是字符串,还可以是其他的任何对象,如果是对象,记得要在dwr中进行转化
function polledDataByServer(data){
dwr.util.setValue("data","我是服务器推过来的数据: "+data.name);
}
</script>
<title>B页面</title>
</head>
<body>
我是B客户端,我不刷新页面,等待服务给我推数据<br><br>
<font color="red" id="data"></font>
</body>
</html>
D页面代码
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<!-- 注意script的顺序,engine.js 需要放在最前面 -->
<script src='<%=request.getContextPath() %>/dwr/engine.js'></script>
<script src='<%=request.getContextPath() %>/dwr/util.js'></script>
<script src='<%=request.getContextPath() %>/dwr/interface/DataPollService.js'></script>
<script type="text/javascript">
window.onload=function(){
//将后台推送数据给前台设置为true
dwr.engine.setActiveReverseAjax(true);
//创建一个属于这个页面的scriptSessionId
DataPollService.createSessionId();
};
//等待服务器的数据推送,data是服务器推过来的数据,不仅仅是字符串,还可以是其他的任何对象,如果是对象,记得要在dwr中进行转化
function polledDataToOneByServer(data){
dwr.util.setValue("data","我是服务器推过来的数据: "+data.name);
}
</script>
<title>D页面</title>
</head>
<body>
我是D客户端,我不刷新页面,等待服务给我推数据<br><br>
<font color="red" id="data"></font>
</body>
</html>
看到这里之后,发现java后台服务器根据前台浏览器初始化的session和调用前台的页面js函数来实现群发还有指定页面发送...这就是dwr的
后台服务器的推送技术