原文地址:https://www.cnblogs.com/momo1210/p/6283252.html
dwr推送方式有三种,这三种方式,都可以在dwr的配置文件中进行相关的配置,若不进行配置,则默认是下面的第一种piggyback。
1、piggyback方式
这是默认的方式。
如果后台有什么内容需要推送到前台,是要等到那个页面进行下一次ajax请求的时候,将需要推送的内容附加在该次请求之后,传回到页面。
只有等到下次请求页面主动发起了,中间的变化内容才传递回页面。
2、comet方式
当服务端建立和浏览器的连接,将页面内容发送到浏览器之后,对应的连接并不关闭,只是暂时挂起。如果后面有什么新的内容需要推送到客户端的时候直接通过前面挂起的连接再次传送数据。
服务器所能提供的连接数目是一定的,在大量的挂起的连接没有关闭的情况下,可能造成新的连接请求不能接入,从而影响到服务质量。
3、polling方式
由浏览器定时向服务端发送ajax请求,询问后台是否有什么内容需要推送,有的话就会由服务端返回推送内容。这种方式和我们直接在页面通过定时器发送 ajax请求,然后 查询后台是否有变化内容的实现是类似的。只不过用了dwr之后这部分工作由框架帮我们完成了。
三种方式配置方式如下,在web.xml中加入
<servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <!-- 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> --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping>
而我使用的comet方式,所以我在web.xml中加入了
<servlet> <servlet-name>dwr</servlet-name> <servlet-class>org.directwebremoting.spring.DwrSpringServlet</servlet-class> <!-- spring 配置dwr --> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <!-- 设置是否允许使用dwr推送技术 --> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>maxWaitAfterWrite</param-name> <param-value>3000</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
要想实现精确推送到特定的页面,要把想要推送的页面上标识一个Id,dwr推送时过滤这个Id,没有标记Id或Id不一致的页面则不推送。
加入如下辅助类,用于标识Id
package com.cqut.service.dwrPush;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.springframework.stereotype.Controller;
@Controller
@RemoteProxy
public class RecipientInitService {
//设置接收的页面的Id,用于精确推送
@RemoteMethod
public void initCode(String recipientCode){
ScriptSession scriptSession = WebContextFactory.get().getScriptSession();
scriptSession.setAttribute("recipientCode", recipientCode); //recipientCode是自己为标记起的名字
}
}
然后加入推送辅助类,根据页面的标记进行精确推送
package com.cqut.service.dwrPush;
import java.util.Collection;
import org.directwebremoting.Browser;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ScriptSessionFilter;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.springframework.stereotype.Controller;
@Controller
@RemoteProxy
public class PushService {
/**
* 推送信息到特定的页面
* @param code 推送到的页面 recipientCode
* @param functionName 前台调用 的JavaScript方法
* @param args 前台调用 的JavaScript方法的参数
*/
@RemoteMethod
public void pushMsg(final String code,final String functionName,final Object... args){
//定义过滤器
ScriptSessionFilter filter = new ScriptSessionFilter() {
public boolean match(ScriptSession session) {
if (session.getAttribute("recipientCode") == null) {
return false;
} else {
return (session.getAttribute("recipientCode")).equals(code);
}
}
};
//执行推送
pushMsgOnFilter(filter, functionName, args);
}
/**
* 根据传递过来的过滤器参数进行页面的推送
* @param filter 过滤器
* @param functionName 前台javascripg要执行的方法
* @param args 前台javascripg要执行方法的参数
*/
public void pushMsgOnFilter(ScriptSessionFilter filter,final String functionName,final Object... args){
Runnable run = new Runnable(){
private ScriptBuffer script = new ScriptBuffer();
public void run() {
//设置要调用的 js及参数
script.appendCall(functionName , args);
//得到所有ScriptSession
Collection<ScriptSession> sessions = Browser.getTargetSessions();
//遍历每一个ScriptSession
for (ScriptSession scriptSession : sessions){
scriptSession.addScript(script);
}
}
};
Browser.withAllSessionsFiltered(filter,run); //使用过滤器实现推送
}
}
在前台需要推送的页面加入下面javascripg代码
//设置页面建立长连接 dwr.engine.setActiveReverseAjax(true); dwr.engine.setNotifyServerOnPageUnload(true); //设置页面标记Id RecipientInitService.initCode("manager");
在后台要推送的页面,使用辅助类实现推送
- dwrPushService.pushMsg( "mamanger","test", "123"); //manager是页面标记,test是js方法,124是test方法的参数
推送实现完成