dwr做comet的完整实现

dwr做comet的完整实现
   场景:页面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;
  }

}

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

你可能感兴趣的:(dwr做comet的完整实现)