DWR3实现从服务器发送消息到网页

来源:互联网 发布:js给div添加class 编辑:程序博客网 时间:2024/05/22 08:07

在项目中使用DWR3实现了从服务器到网页的消息发送,主要参考了http://www.blogjava.net/stevenjohn/archive/2012/07/07/382447.html点击打开链接

该帖子中的示例,以及官网http://directwebremoting.org/dwr/index.html点击打开链接了解DWR的原理以及建议。由于在项目开发中实现的该功能没有写具体的演示Demo,所以没有源码下载了,具体开发流程如下:

1:在pom.xml中:

<dependency><groupId>org.directwebremoting</groupId><artifactId>dwr</artifactId><version>3.0.1-RELEASE</version></dependency>
2:在web.xml中:

<span style="white-space:pre"></span><servlet><display-name>DWR Servlet</display-name><servlet-name>dwr-invoker</servlet-name><servlet-class>com.edu.common.application.dwr.utils.DwrServlet</servlet-class><init-param><description>在服务器激活Reverse Ajax</description><param-name>activeReverseAjaxEnabled</param-name><param-value>true</param-value></init-param><init-param><description>默认值 500 (ms)</description><param-name>maxWaitAfterWrite</param-name><param-value>1000</param-value></init-param><init-param><param-name>debug</param-name><param-value>true</param-value></init-param><init-param><param-name>logLevel</param-name><param-value>WARN</param-value></init-param><load-on-startup>3</load-on-startup></servlet><servlet-mapping><servlet-name>dwr-invoker</servlet-name><url-pattern>/dwr/*</url-pattern></servlet-mapping>

在服务端,只有设置了activeReverseAjaxEnabled为true,并且在网页端设置了dwr.engine.setActiveReverseAjax(true);才可以实现从服务器推送消息到网页。官网的定义是Reverse Ajax(翻译为:反转Ajax),在网页中的代码如下:

<span style="white-space:pre"></span><script type="text/javascript">$(function() {//连接DWR服务器,, engine.js加载完,就创建ScriptSession,在ScriptSessionListener中设置了用户信息//从客户端激活Reverse Ajaxdwr.engine.setActiveReverseAjax(true);$(".mytable").footable();});function showMessage(autoMessage) {$("#rrrr").append(autoMessage);}</script>

3:在WEB-INF/dwr.xml,配置文件如下:

<!DOCTYPE dwr PUBLIC    "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN"    "http://directwebremoting.org/schema/dwr30.dtd"><dwr><allow><create creator="new" javascript="Chat"><param name="class" value="com.sobey.edu.common.application.dwr.Chat" /></create></allow></dwr>

配置文件中定义的Chat类的具体代码如下:

public class Chat {private static Logger logger = LoggerFactory.getLogger(Chat.class);/** * @param userid * @param functionName * @param message */public void sendMessage(final Long userid, final String functionName,final String message) {Browser.withAllSessionsFiltered(new UserScriptSessionFilter(UserScriptSessionFilter.ATTRIBUTE_NAME, userid),new Runnable() {public void run() {// 只向满足ScriptSessionFilter过滤器的ScriptSessions发送消息
<span style="white-space:pre"></span>// 向满足条件的Session发送消息,functionName为网页端定义的方法名ScriptSessions.addFunctionCall(functionName, message);}});}/** * 创建ScriptSession 回话连接 */public void connect() {ScriptSession scriptSession = WebContextFactory.get().getScriptSession();Long userId = (Long) scriptSession.getAttribute(UserScriptSessionFilter.ATTRIBUTE_NAME);logger.debug("DWR连接,ScriptSessionId:{} 设置用户属性为:{}",scriptSession.getId(), userId);}}
在该类中定义了验证创建ScriptSession时设置的用户信息。并且定义了发送消息的方法sendMessage。

Browser类是操作ScriptSession会话session的工具类。其常用的方法有如下:

withAllSessions(Runnable task),向所有的Session执行task。

withAllSessionsFiltered(ScriptSessionFilter filter,Runnable task),向满足特定条件的Session发送消息。在Chat类中定义的发送消息方法中定义了UserScriptSessionFilter,只有设置了userId属性的Session才发送消息,代码如下:

public class UserScriptSessionFilter implements ScriptSessionFilter {public static String ATTRIBUTE_NAME="userId";private String attributeName;// 属性名称private Long userId;// 用户idpublic UserScriptSessionFilter(String attributeName, Long userId) {super();this.attributeName = attributeName;this.userId = userId;}@Overridepublic boolean match(ScriptSession session) {// 获取存储的用户idLong userSession = (Long) session.getAttribute(attributeName);if (null == userSession) {return false;}if (userSession.toString().equals(userId.toString())) {return true;}return false;}}
4:介绍下服务器推送消息到指定用户的网页实现过程及原理。在网页端使用DWR需要引入如下的js

<script type="text/javascript" src="{项目路径}/dwr/engine.js"></script><script type="text/javascript" src="{项目路径}/dwr/util.js"></script></span>
<script type="text/javascript" src="{项目路径}/dwr/interface/Chat.js"></script></span>
这三个都是由DWR自动生成,第三个是根据dwr.xml配置文件来生成的。
并且,在dwr/util.js在jsp页面加载被引用后就会触发DWR创建ScriptSession;所以在ScriptSession中设置属性就要在ScriptSession创建以后才可以设置。
我们在org.directwebremoting.servlet.DwrServlet被初始化时,添加ScriptSessionListener监听到ScriptSession创建然后设置属性既可。具体代码如下:
public class DwrServlet extends org.directwebremoting.servlet.DwrServlet {/** *  */private static final long serialVersionUID = -4998536155299066763L;@Overridepublic Container createContainer(ServletConfig servletConfig) {Container container = null;try {container = super.createContainer(servletConfig);ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);manager.addScriptSessionListener(new UserScriptSessionListener());} catch (ServletException e) {e.printStackTrace();}return container;}}

UserScriptSessionListener是ScriptSession创建时设置用户信息的一个监听器,具体代码如下:

public class UserScriptSessionListener implements ScriptSessionListener {private static Logger logger = LoggerFactory.getLogger(UserScriptSessionListener.class);@Overridepublic void sessionCreated(ScriptSessionEvent ev) {ScriptSession scriptSession = ev.getSession();//当前登录用户的信息,可以保存在HttpSession,http会话// HttpSession session = WebContextFactory.get().getSession();        // String userId = (String) session.getAttribute("userId");User user = UserUtils.getUser();scriptSession.setAttribute(UserScriptSessionFilter.ATTRIBUTE_NAME, user.getId());logger.debug("用户 {} 创建DWR连接,ScriptSessionId为: {}", user.getName(),scriptSession.getId());}@Overridepublic void sessionDestroyed(ScriptSessionEvent ev) {logger.debug("DWR连接断开,ScriptSessionId为:  {}", ev.getSession().getId());}}
至此,项目发布后访问该网页,就会创建一个设置当前登录用户信息的ScriptSession的会话。在在服务端调用Chat类的sendMessage方法就可以发送消息到指定网页端了。java代码如下:

<span style="white-space:pre"></span>Chat chat = new Chat();chat.sendMessage(UserUtils.getUser().getId(), "showMessage","refrush");

showMessage为网页端定义的js方法,代码如下:
<span style="white-space:pre"></span>function showMessage(autoMessage) {$("#rrrr").append(autoMessage);}













0 0
原创粉丝点击