新人 熟手 专家 大师 宗师 ...

BlogJava 首页 新随笔 联系 聚合 管理
  2 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks
   场景:页面comet.jsp接受服务器推送的信息并显示,页面action.jsp执行一个动作,调用DwrServer.perform方法,perform方法做某些事,并发送事件信息PerformInfo。NotifyClient监听事件,当接收到PerformInfo后,把PerformInfo的信息发送到comet.jsp页面。这个场景模拟了页面1执行了一个时间比较长或复杂的任务,任务执行情况可以反馈到页面2(比如模式窗口)。
   信息载体PerformInfo.java
package application.comet;

import java.util.Date;

public class PerformInfo {
  
private int id;
  
private String msg;
  
private Date   time;
  
/**
   * 
@return the id
   
*/
  
public int getId() {
    
return id;
  }
  
/**
   * 
@param id the id to set
   
*/
  
public void setId(int id) {
    
this.id = id;
  }
  
/**
   * 
@return the msg
   
*/
  
public String getMsg() {
    
return msg;
  }
  
/**
   * 
@param msg the msg to set
   
*/
  
public void setMsg(String msg) {
    
this.msg = msg;
  }
  
/**
   * 
@return the time
   
*/
  
public Date getTime() {
    
return time;
  }
  
/**
   * 
@param time the time to set
   
*/
  
public void setTime(Date time) {
    
this.time = time;
  }

}
   Spring的事件InfoEvent.java
package application.comet;

import org.springframework.context.ApplicationEvent;

public class InfoEvent extends ApplicationEvent {
   
public InfoEvent(Object source){
     
super(source);
   }
}

   DwrService.java 执行任务,就是写了100遍PerformInfo,需要实现ApplicationContextAware接口
package application.comet;

import java.util.Date;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;

public class DwrService implements ApplicationContextAware{
  
private ApplicationContext ctx;
  
public void setApplicationContext(ApplicationContext ctx) {
    
this.ctx = ctx;
  }
  
public void perform(){
    
for (int i=0;i<100;i++){
      PerformInfo info 
= new PerformInfo();
      info.setId(i);
      info.setMsg(
"发送"+i+"信息");
      info.setTime(
new Date());
      InfoEvent evt 
= new InfoEvent(info);
      ctx.publishEvent(evt);
    }
  }

}

NotifyClient.java监听事件,发送信息到页面。实现ApplicationListener,ServletContextAware接口,对中文需要编码
package application.comet;

import java.io.UnsupportedEncodingException;
import java.util.Collection;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import org.springframework.web.context.ServletContextAware;
import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

public class NotifyClient implements ApplicationListener,ServletContextAware{
  
private ServletContext servletContext = null;
  
public void setServletContext( ServletContext servletContext )
  {
    
this.servletContext = servletContext;
  }    
  
  
public void onApplicationEvent(ApplicationEvent event) {
    
if (event instanceof InfoEvent) {
      PerformInfo info 
= (PerformInfo)event.getSource();
      System.out.println(info.getMsg());
      
//Collection<ScriptSession> sessions=ctx.getAllScriptSessions();
      ServerContext ctx = ServerContextFactory.get(servletContext );
      Collection
<ScriptSession> sessions = 
           ctx.getScriptSessionsByPage(
"/dwrcomet/comet.jsp");  
      
for (ScriptSession session : sessions) {
          ScriptBuffer script 
= new ScriptBuffer();
          String s
=null;
          String s2 
= null;
          
try {
            s 
= java.net.URLEncoder.encode(info.getMsg(),"UTF-8");
            s2 
= java.net.URLEncoder.encode("通知结束","UTF-8");
          } 
catch (UnsupportedEncodingException e) {
            e.printStackTrace();
          }
          
if (info.getId()<99){
            script.appendScript(
"putInfo('")
            .appendScript(info.getId()
+":"+s)
            .appendScript(
"');");
          }
else{
            script.appendScript(
"alert(decodeURI('").
                   appendScript(s2).appendScript(
"'));");
          }
          
          System.out.println(script.toString());
          session.addScript(script);
      }        
    }
  }

}

action.jsp执行任务
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String root 
= request.getContextPath();
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>
    
<title>doing</title>
    
    
<meta http-equiv="pragma" content="no-cache">
    
<meta http-equiv="cache-control" content="no-cache">
    
<meta http-equiv="expires" content="0">    
<script type='text/javascript' src='<%=root%>/dwr/engine.js'></script>
<script type='text/javascript' src='<%=root%>/dwr/util.js'></script>
<script type='text/javascript' src='<%=root%>/dwr/interface/DwrService.js'></script>
  
</head>
  
  
<body>
  
<input name='action' onclick='DwrService.perform();' type="button" value="行动"/>
  
</body>
</html>

comet.jsp接受信息。关键是增加onload="dwr.engine.setActiveReverseAjax(true);",还可以根据user或session id判断是否是自己的信息.
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String root 
= request.getContextPath();
String basePath 
= request.getScheme()+"://"+request.getServerName()+":"
+request.getServerPort()+root+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  
<head>
    
<base href="<%=basePath%>">
    
    
<title>Comet with DWR</title>
    
    
<meta http-equiv="pragma" content="no-cache">
    
<meta http-equiv="cache-control" content="no-cache">
    
<meta http-equiv="expires" content="0">    
  
</head>
  
<body onload="dwr.engine.setActiveReverseAjax(true);">
<script type='text/javascript' src='<%=root%>/dwr/engine.js'></script>
<script type='text/javascript' src='<%=root%>/dwr/util.js'></script>
<script type="text/javascript">
    var user 
= '<%=request.getParameter("user")%>';
    
    function putInfo(data) {
       var d 
= decodeURI(data);
       var text 
= dwr.util.getValue('info');       
       dwr.util.setValue(
'info',text+'\n'+d);
    }
</script>
<br/>
<textarea rows="20" cols="100" id='info'></textarea>
</body>
</html>

applicationContext.xml配置了NotifyClient和DwrService,这两个bean实现了ApplicationContextAware
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  
<bean id="notifyClient" class="application.comet.NotifyClient">
  
</bean>
  
<bean id="dwrService" class="application.comet.DwrService"></bean>
</beans>

dwr.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
    "http://www.getahead.ltd.uk/dwr/dwr10.dtd"
>
<dwr>
  
<allow>
    
<create creator="spring" javascript="DwrService">
      
<param name="beanName" value="dwrService" />
    
</create>
  
</allow>
</dwr>


web.xml定义了dwr的comet控制,关键是pollAndCometEnabled=true
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
    xmlns
="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>
    
<context-param>
        
<param-name>contextConfigLocation</param-name>
        
<param-value>/WEB-INF/app*.xml</param-value>
    
</context-param>
    
<servlet>
        
<servlet-name>context</servlet-name>
        
<servlet-class>
            org.springframework.web.context.ContextLoaderServlet
        
</servlet-class>
        
<load-on-startup>1</load-on-startup>
    
</servlet>

 
<!--dwr servlet-->
  
<servlet>
    
<servlet-name>dwr-invoker</servlet-name>
    
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
    
<init-param>
        
<param-name>debug</param-name>
        
<param-value>true</param-value>
    
</init-param>
    
<init-param>
      
<param-name>pollAndCometEnabled</param-name>
      
<param-value>true</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>
</web-app>

运行时要先打开comet.jsp,然后执行action.jsp

posted on 2008-07-04 11:46 记忆力 阅读(4514) 评论(3)  编辑  收藏 所属分类: ajax

Feedback

# re: dwr做comet的完整实现 2008-12-15 17:07 杨俊
有DwrService.js文件么  回复  更多评论
  

# re: dwr做comet的完整实现[未登录] 2009-08-31 14:17 阿哲
现在我这个能跑得起来

但是comet.jsp

没有数据显示阿

砸毁尸阿  回复  更多评论
  

# re: dwr做comet的完整实现 2011-01-23 11:51 fengyp
NotifyClient.java中Collection<ScriptSession> sessions =
ctx.getScriptSessionsByPage("/dwrcomet/comet.jsp");
记得改dwrcomet为自己的应用名  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: