浏览 7043 次
锁定老帖子 主题:DWR3-ReverseAjax-半推实现
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-01-05
最后修改:2010-01-07
第一次发帖,直奔主题。
首先,配置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 onload="dwr.engine.setActiveReverseAjax(true)"> </body> </html> 好了,至此半推结束. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-06-21
我看了你写的BLOG,写的一篇关于DWR半推实现.对里面的有两句代码没有弄懂.
DefaultScriptSession old=sessionMap.get(ssId); public Collection getAllScriptSessions(){ return sessionMap.values(); } 如获LZ赐教,不胜感激! |
|
返回顶楼 | |
发表时间:2010-06-21
就是sessionMap不是很清楚,从那里来的.
|
|
返回顶楼 | |
发表时间:2010-06-23
jroad 写道 就是sessionMap不是很清楚,从那里来的.
sessionMap 是从父类集成过来的 |
|
返回顶楼 | |
发表时间:2010-08-30
IUserReqService.GCZ.addObserver(this);//注册观察者 这个能告诉怎么实现的吗? |
|
返回顶楼 | |
发表时间:2010-08-30
java_jian 写道 IUserReqService.GCZ.addObserver(this);//注册观察者 这个能告诉怎么实现的吗? public interface IUserReqService { /** * 观察者. */ Observable GCZ = new java.util.Observable() ........ ....... |
|
返回顶楼 | |
发表时间:2010-08-30
能把service层 代码都贴出来嘛?
想学习一下, @Override public Collection<ScriptSession> getAllScriptSessions() { return super.getAllScriptSessions(); } 还有这句。 有泛型的。 |
|
返回顶楼 | |
发表时间:2010-08-30
你这个半推,实现的是用户的在线列表吧?
能把用到的类都贴出来吗? |
|
返回顶楼 | |
发表时间:2010-09-02
java_jian 写道 你这个半推,实现的是用户的在线列表吧?
能把用到的类都贴出来吗? 实现的是消息即时提醒,就像人人网的回复提醒 |
|
返回顶楼 | |
发表时间:2010-09-02
比较关心Performance
lz测过可以支持多少链接吗? |
|
返回顶楼 | |