DWR Reverse Ajax功能实践的要点

Reverse Ajax主要是在BS架构中,从服务器端向多个浏览器主动推数据的一种技术。它的一种实现就是客户端向服务器请求后,服务器不立即回应,从而导致一个http长连接,等到有更新数据的时候,再利用这个连接“主动”向客户端回送。
如果是初次接触,那一定要看下这篇文章
其中,详述了这种技术和JETTY服务器Continuations功能结合时的强大性能:运行在非阻塞方式下,当多个客户端请求时不会占用过多线程。
最后,此文申明DWR的实现已经天然使用了JETTY这一功能。所以使用DWR还是非常有好处的。如何使用及示例上面这篇文章已经有说明,下面就以我实际使用中碰到的问题和要点做个说明。


首先,说一下代码的组织和声明。
将使用到Reverse Ajax的代码归入一个类,比如是NotifyClient,并用spring的bean来声明。在将要用到这个类的地方(NodeSvcImpl类),也通过成员变量引入:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < bean id ="notifyClient" class ="com.hhh.nms.remote.NotifyClient" >
</ bean >

< bean id ="nodeSvcImpl" class ="com.hhh.nms.magic.NodeSvcImpl" >
< property name ="notifyClient" ref ="notifyClient" />
</ bean >


然后在dwr.xml里这样声明:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> < dwr >
< allow >
< create creator ="spring" javascript ="NotifyClient" >
< param name ="beanName" value ="notifyClient" />
< include method ="updateService" />
</ create >
</ allow >
</ dwr >



其次一个要点是,如果你不是在DWR所开的线程中使用Reverse Ajax,那WebContextFactory.get()会返回空,这是因为只有DWR自己的线程才会初始化它。那如果你是在DWR之外使用,比如说收到JMS消息,或者UDP消息后,想通知所有客户端,你就要用到ServerContext。
要得到ServerContext,就需要用到spring的ServletContextAware接口,下面是完整代码:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> package com.hhh.nms.remote;

import org.apache.log4j.Logger;

import javax.servlet.ServletContext;
import org.springframework.web.context.ServletContextAware;

import java.util.Collection;

import org.directwebremoting.ScriptBuffer;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.proxy.dwr.Util;


public class NotifyClient implements ServletContextAware{
static Loggerlogger = Logger.getLogger(NotifyClient. class .getName());

private ServletContextservletContext = null ;
public void setServletContext(ServletContextservletContext)
{
this .servletContext = servletContext;
}

public int serviceUpdate(Stringstr1,Stringstr2){
logger.info(
" entered " );

logger.info(
" WebContext1 " + servletContext);

ServerContextctx
= ServerContextFactory.get(servletContext);

// GenerateJavaScriptcodetocallclient-side

// WebContextctx=WebContextFactory.get();
logger.info( " WebContext " + ctx);
if (ctx != null ){
// StringcurrentPage=ctx.getCurrentPage();
// logger.info("currentpage:"+currentPage);

ScriptBufferscript
= new ScriptBuffer();
script.appendScript(
" updatePoint( " )
.appendData(str1)
.appendScript(
" , " )
.appendData(str2)
.appendScript(
" ); " );

// Pushscriptouttoclientsviewingthepage
Collection < ScriptSession > sessions =
ctx.getScriptSessionsByPage(
" /ebnms/index.eb?do=dwrtest " );

logger.info(
" jspsessionsize: " + sessions.size());

// or

Collection
< ScriptSession > sessions2 =
ctx.getAllScriptSessions();

logger.info(
" allsessionsize: " + sessions2.size());


for (ScriptSessionsession:sessions2){
session.addScript(script);
}
}

return 0 ;
}
}



另外,ScriptBuffer的appendScript方法是插入原始字串,appendData会根据参数类型做相应转换。

你可能感兴趣的:(Ajax)