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;
  }

}
   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

你可能感兴趣的:(java,DWR)