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
DwrService.java 执行任务,就是写了100遍PerformInfo,需要实现ApplicationContextAware接口
NotifyClient.java监听事件,发送信息到页面。实现ApplicationListener,ServletContextAware接口,对中文需要编码
action.jsp执行任务
comet.jsp接受信息。关键是增加onload="dwr.engine.setActiveReverseAjax(true);",还可以根据user或session id判断是否是自己的信息.
applicationContext.xml配置了NotifyClient和DwrService,这两个bean实现了ApplicationContextAware
dwr.xml
web.xml定义了dwr的comet控制,关键是pollAndCometEnabled=true
运行时要先打开comet.jsp,然后执行action.jsp
信息载体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;
}
}
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;
}
}
package
application.comet;
import org.springframework.context.ApplicationEvent;
public class InfoEvent extends ApplicationEvent {
public InfoEvent(Object source){
super (source);
}
}
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);
}
}
}
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);
}
}
}
}
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 >
<%
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 >
<%
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 >
<! 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 >
<! 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 >
< 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