第一次发帖,直奔主题。
首先,配置web.xml加入参数开启ReverseAjax
<servlet>
<servlet-name>dwr</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>org.directwebremoting.extend.ScriptSessionManager</param-name>
<param-value>com.cssweb.business.dwr.CustomSSManager</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
注意红色部分,即半推实现方式:加入自己的ScriptSessionManager.由于dwr每次刷新激活ReverseAjax的页面都会创建一个ScriptSession,这里要自己管理它以便实现半推,同时和HttpSession做同步,以最后请求的ScriptSession为准,销毁之前的ScriptSession。
下面就是CustomSSManager:
import java.util.Collection;
import javax.servlet.http.HttpSession;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.event.ScriptSessionEvent;
import org.directwebremoting.event.ScriptSessionListener;
import org.directwebremoting.impl.DefaultScriptSession;
import org.directwebremoting.impl.DefaultScriptSessionManager;
import com.cssweb.business.user.pojo.User;
import com.cssweb.constans.CONST;
/**
*
* 扩展ScriptSessionManager.
* @author congyy
* @createTime 2010-1-3
*/
public class CustomSSManager extends DefaultScriptSessionManager {
public static final String SS_ID = "DWR_ScriptSession_Id";
public CustomSSManager() {
addScriptSessionListener(new ScriptSessionListener(){
public void sessionCreated(ScriptSessionEvent event) {
ScriptSession scriptSession = event.getSession(); // 获取新创建的SS
HttpSession httpSession = WebContextFactory.get().getSession();// 获取构造SS的用户的HttpSession
User user = (User)httpSession.getAttribute(CONST.SESSION_USER);
if(user ==null){
scriptSession.invalidate();
httpSession.invalidate();
return;
}
String ssId = (String) httpSession.getAttribute(SS_ID);
if (ssId != null) {
DefaultScriptSession old=sessionMap.get(ssId);
if(old!=null)CustomSSManager.this.invalidate(old);
}
httpSession.setAttribute(SS_ID, scriptSession.getId());
scriptSession.setAttribute("userId", user.getId());//此处将userId和scriptSession绑定
}
public void sessionDestroyed(ScriptSessionEvent event) {}
});
ReqReverseAjax.manager=this;//将自己暴露ReverseAjax业务处理类
}
public Collection getAllScriptSessions(){
return sessionMap.values();
}
}
关于上述代码 :User为POJO类,CONST为常量放置接口,如session中的用户KEY.
然后是ReverseAjax业务处理类:
package com.cssweb.business.dwr;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.extend.ScriptSessionManager;
import com.cssweb.business.user.pojo.UserReq;
import com.cssweb.business.user.service.IUserReqService;
/**
* Observer实现,监听事件,然后推送给指定用户.
*/
public class ReqReverseAjax implements Observer{
static ScriptSessionManager manager ;
public ReqReverseAjax() {
IUserReqService.GCZ.addObserver(this);//注册观察者
}
public void update(Observable o, Object arg) {
final UserReq req = (UserReq) arg;
final Long userId = req.getToId();//获取事件要通知的用户的id
Collection<ScriptSession> coll = manager.getAllScriptSessions();//获取当前所有ScriptSession
for(ScriptSession ss : coll) {
if(ss.getAttribute("userId").equals(userId)){
ss.addScript(new ScriptBuffer().appendScript("update").appendScript("(").appendData(req).appendScript(");"));//找到符合要求的,推送事件
break;
}
}
}
}
然后在WEB-INF/下丢一个dwr.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd"> <dwr> <allow> <create creator="new" scope="application"> <param name="class" value="com.cssweb.business.dwr.ReqReverseAjax"/> </create> <convert converter="bean" match="com.cssweb.business.user.pojo.UserReq"/> </allow> </dwr>
至此,服务端配置完全结束,实现半推。
页面上实现如下:
index.jsp,加上框架,减少对reverseAjax.html页面的刷新量
<%@ page pageEncoding="UTF-8"%>
<frameset rows="*" cols="0,*" border="0">
<frame src="${contextPath }/jsp/ajax/user/reverseAjax.html#${contextPath }" frameborder="0">
<frame src="${contextPath }/jsp/user/index.do"/>
</frameset>
reverseAjax.html:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript">
function update(req) {
//在这里处理服务器推过来的信息
}
var url = self.location.href;
var ctx = url.slice(url.indexOf('#')+1);
document.write("<script src='"+ctx+"/dwr/engine.js'><\/script>");
</script>
</head>
<body οnlοad="dwr.engine.setActiveReverseAjax(true)">
</body>
</html>
好了,至此半推结束.