dwr反推技术

ajaxDreamer 2012-03-09

DWR2.x的推技术

DWR2.x的推技术也叫DWR Reverse Ajax(逆向Ajax)主要是在BS架构中,从服务器端向多个浏览器主动推数据的一种技术。在DWR所开的线程中使用Reverse Ajax时,通过WebContextFactory.get()获取WebContext对象,进而获取脚本Session。在DWR之外使用Reverse Ajax时,就要用到ServerContext,在Spring环境中要得到ServerContext,就需要用到Spring的ServletContextAware接口。

一、Reverse Ajax的实现有3种方式:

      DWR的逆向Ajax主要包括两种模式:主动模式和被动模式。其中主动模式包括polling和comet两种,被动模式只有piggyback这一种。

     1、piggyback方式

           这是默认的方式。

           如果后台有什么内容需要推送到前台,是要等到那个页面进行下一次ajax请求的时候,将需要推送的内容附加在该次请求之后,传回到页面。只有等到下次请求页面主动发起了,中间的变化内容才传递回页面。

      2、comet方式

           当服务端建立和浏览器的连接,将页面内容发送到浏览器之后,对应的连接并不关闭,只是暂时挂起。如果后面有什么新的内容需要推送到客户端的时候直接通过前面挂起的连接再次传送数据。服务器所能提供的连接数目是一定的,在大量的挂起的连接没有关闭的情况下,可能造成新的连接请求不能接入,从而影响到服务质量。

      3、polling方式

           由浏览器定时向服务端发送ajax请求,询问后台是否有什么内容需要推送,有的话就会由服务端返回推送内容。这种方式和我们直接在页面通过定时器发送ajax请求,然后查询后台是否有变化内容的实现是类似的。只不过用了dwr之后这部分工作由框架帮我们完成了。

二、使用DWR的推技术的步骤

     1、在web.xml文件中增加以下配置信息

Xml代码  

 <!-- 开始DWR配置 -->

<servlet>

<servlet-name>dwr-invoker</servlet-name>

<!--

<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>

-->

<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>

<init-param>

<param-name>debug</param-name>

<param-value>true</param-value>

</init-param>

<!--dwr反转-->

<!--1、piggyback方式

这是默认的方式。

如果后台有什么内容需要推送到前台,是要等到那个页面进行下一次ajax请求的时候,将需要推送的内容附加在该次请求之后,传回到页面。

只有等到下次请求页面主动发起了,中间的变化内容才传递回页面。

2、comet方式

当服务端建立和浏览器的连接,将页面内容发送到浏览器之后,对应的连接并不关闭,只是暂时挂起。如果后面有什么新的内容需要推送到客户端的时候直接通过前面挂起的连接再次传送数据。

服务器所能提供的连接数目是一定的,在大量的挂起的连接没有关闭的情况下,可能造成新的连接请求不能接入,从而影响到服务质量。

3、polling方式

由浏览器定时向服务端发送ajax请求,询问后台是否有什么内容需要推送,有的话就会由服务端返回推送内容。这种方式和我们直接在页面通过定时器发送ajax请求,然后查询后台是否有变化内容的实现是类似的。只不过用了dwr之后这部分工作由框架帮我们完成了。

-->

<!--DWR默认采用piggyback方式-->

<!--使用polling和comet的方式-->

<init-param>

<param-name>pollAndCometEnabled</param-name>

<param-value>true</param-value>

</init-param>

<!--comet方式-->

<!--

<init-param>

<param-name>activeReverseAjaxEnabled</param-name>

<param-value>true</param-value>

</init-param>

-->

<!--polling方式:在comet方式的基础之上,再配置以下参数-->

<!--

<init-param>

<param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>

<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>

-->

<init-param>

<param-name>crossDomainSessionSecurity</param-name>

<param-value>false</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>

<listener>

<listener-class>

org.directwebremoting.servlet.EfficientShutdownServletContextAttributeListener

</listener-class>

</listener>

<listener>

<listener-class>

org.directwebremoting.servlet.EfficientShutdownServletContextListener

</listener-class>

</listener>

 <!-- 结束DWR配置 -->

2、在dwr.xml中增加以下配置信息

Xml代码

<?xml version="1.0" encoding="UTF-8"?> 

<!DOCTYPEdwrPUBLIC"-//GetAheadLimited//DTDDirectWebRemoting2.0//EN""http://getahead.org/dwr//dwr20.dtd">

<dwr>

<allow>

<createcreator="new"javascript="DWRAction">

<paramname="class"value="com.tcps.action.DwrActionTest"/>

<includemethod="DwrTest"/>

<includemethod="sessionDestory"/>

</create>

<createcreator="new"javascript="DWRReverse">

<paramname="class"value="com.tcps.action.DWRReverse"/>

</create>

<convertconverter="bean"match="com.tcps.model.User">

<paramname="include"value="username,password"/>

</convert>

</allow>

</dwr>

3、pojo类User的源码

Java代码

public class User implements java.io.Serializable {

    // Fields   

     private Integer id;

privateStringusername;

privateStringpassword;

privateStringage;

privateStringtel;

     private String sessionid;

    // Constructors

    /** default constructor */

publicUser(){

    }

 /** minimal constructor */

publicUser(Integerid,Stringusername,Stringpassword){

this.id=id;

this.username=username;

this.password=password;

}

/**fullconstructor*/

publicUser(Integerid,Stringusername,Stringpassword,Stringage,Stringtel,Stringsessionid){

this.id=id;

this.username=username;

this.password=password;

this.age=age;

this.tel=tel;

this.sessionid=sessionid;

}

@Override

publicStringtoString(){

returnthis.username+this.password;

}

    // Property accessors

    public Integer getId() {

returnthis.id;

}

publicvoidsetId(Integerid){

this.id=id;

    }

    public String getUsername() {

returnthis.username;

}

publicvoidsetUsername(Stringusername){

this.username=username;

    }

    public String getPassword() {

returnthis.password;

}

publicvoidsetPassword(Stringpassword){

this.password=password;

    }

    public String getAge() {

returnthis.age;

}

publicvoidsetAge(Stringage){

this.age=age;

    }

    public String getTel() {

returnthis.tel;

}

publicvoidsetTel(Stringtel){

this.tel=tel;

    }

 public String getSessionid() {

returnsessionid;

 }

 public void setSessionid(String sessionid) {

this.sessionid=sessionid;

 }

4、DWRReverse类源码

Java代码  

public class DWRReverse extends AbstractAction {    public static WebContext wctx = null;

    public static void sendMessage(User monitor) {

if(wctx==null){

wctx=WebContextFactory.get();

}

ScriptBufferscript=newScriptBuffer();

//执行js方法

if(monitor!=null){

StringBuffersb=newStringBuffer();

sb.append(monitor.getId()).append(",");

sb.append(monitor.getUsername()).append(",");

sb.append(monitor.getPassword()).append(",");

sb.append(monitor.getAge()).append(",");

sb.append(monitor.getTel());

script.appendScript("receiveMessages('").appendData(sb.toString())

.appendScript("');");

}

ServerContextsctx=ServerContextFactory.get(wctx.getServletContext());

Collection<ScriptSession>scriptSessions=sctx.getScriptSessionsByPage(wctx.getCurrentPage());

Utilutil=newUtil(scriptSessions);

//可以设置样式等

//util.setStyle("test","display","none");

for(ScriptSessionsession:scriptSessions){

session.addScript(script);

}

}

}

5、JSP页面源码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

Stringpath=request.getContextPath();

StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

<basehref="<%=basePath%>">

<title>MyJSP'dwrReverse.jsp'startingpage</title>

<scripttype='text/javascript'src='<%=basePath%>/dwr/interface/DWRReverse.js'></script>

<scripttype='text/javascript'src='<%=basePath%>/dwr/engine.js'></script>

<scripttype='text/javascript'src='<%=basePath%>/dwr/util.js'></script>

<metahttp-equiv="pragma"content="no-cache">

<metahttp-equiv="cache-control"content="no-cache">

<metahttp-equiv="expires"content="0">

<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">

<metahttp-equiv="description"content="Thisismypage">

<!--

<linkrel="stylesheet"type="text/css"href="styles.css">

-->

<scripttype="text/javascript">

functiongetData(){

DWRReverse.sendMessage(null);

}

functionreceiveMessages(message){

varmsg=eval("("+message+")");

vartemp=msg.split(",");

varusername=temp[1];

varpassword=temp[2];

varage=temp[3];

vartel=temp[4];

varnewRow=document.getElementById('tableData').insertRow(2);

varcell0=newRow.insertCell(0);

varcell1=newRow.insertCell(1);

varcell2=newRow.insertCell(2);

varcell3=newRow.insertCell(3);

cell0.innerHTML=username;

cell1.innerHTML=password;

cell2.innerHTML=age;

cell3.innerHTML=tel;

}

</script>

</head>

<!--注:这个是要在使用reverse-ajax的页面必须的-->

<bodyonload="dwr.engine.setActiveReverseAjax(true);getData();">

<divalign="center">

<tabletitle=用户表class="list"align="center"id="tableData">

<trid="titleData">

<tdcolspan="4">

用户表

</td>

<tdcolspan="1"onclick="getData()"style="size:10px">

<ahref="#"></a>

</td>

</tr>

<trid="headData"bgcolor="#fffce7"style="color:#968054">

<tdwidth="9%">

用户名

</td>

<tdwidth="20%">

密码

</td>

<tdwidth="33%">

年龄

</td>

<tdwidth="22%">

电话

</td>

</tr>

</table>

</div>

</body>

</html>

最后,为了测试,后台实现定时器:

public class SampleTask extends TimerTask {

    private ServletContext context;    private static boolean isRunning = false;

    public SampleTask(ServletContext context) {

this.context=context;

    }

    @Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

if(!isRunning){

isRunning=true;

System.out.println("开始执行指定任务");

if(DWRReverse.wctx!=null){

Useruser=newUser(1,"tom","123456","10","13909876543","");

DWRReverse.sendMessage(user);

}

isRunning=false;

//context.log("指定任务执行结束");

}else{

//context.log("上一次任务执行还未结束");

        }

    }

}

相关推荐

mmywcoco / 0评论 2020-06-06