如果是初次接觸,那一定要看下這篇文章
其中,詳述了這種技術(shù)和JETTY服務(wù)器Continuations功能結(jié)合時的強(qiáng)大性能:運(yùn)行在非阻塞方式下,當(dāng)多個客戶端請求時不會占用過多線程。
最后,此文申明DWR的實(shí)現(xiàn)已經(jīng)天然使用了JETTY這一功能。所以使用DWR還是非常有好處的。如何使用及示例上面這篇文章已經(jīng)有說明,下面就以我實(shí)際使用中碰到的問題和要點(diǎn)做個說明。
首先,說一下代碼的組織和聲明。
將使用到Reverse Ajax的代碼歸入一個類,比如是NotifyClient,并用spring的bean來聲明。在將要用到這個類的地方(NodeSvcImpl類),也通過成員變量引入:
<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>
</bean>
<bean id="nodeSvcImpl" class="com.hhh.nms.magic.NodeSvcImpl">
<property name="notifyClient" ref="notifyClient"/>
</bean>
然后在dwr.xml里這樣聲明:
<dwr>
<allow>
<create creator="spring" javascript="NotifyClient">
<param name="beanName" value="notifyClient"/>
<include method="updateService" />
</create>
</allow>
</dwr>
<allow>
<create creator="spring" javascript="NotifyClient">
<param name="beanName" value="notifyClient"/>
<include method="updateService" />
</create>
</allow>
</dwr>
其次一個要點(diǎn)是,如果你不是在DWR所開的線程中使用Reverse Ajax,那WebContextFactory.get()會返回空,這是因?yàn)橹挥蠨WR自己的線程才會初始化它。那如果你是在DWR之外使用,比如說收到JMS消息,或者UDP消息后,想通知所有客戶端,你就要用到ServerContext。
要得到ServerContext,就需要用到spring的ServletContextAware接口,下面是完整代碼:
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 Logger logger = Logger.getLogger (NotifyClient.class.getName());
private ServletContext servletContext = null;
public void setServletContext( ServletContext servletContext )
{
this.servletContext = servletContext;
}
public int serviceUpdate (String str1, String str2) {
logger.info ("entered");
logger.info ("WebContext1"+servletContext);
ServerContext ctx = ServerContextFactory.get(servletContext );
// Generate JavaScript code to call client-side
// WebContext ctx = WebContextFactory.get();
logger.info ("WebContext"+ctx);
if (ctx != null) {
//String currentPage = ctx.getCurrentPage();
//logger.info ("current page:" + currentPage);
ScriptBuffer script = new ScriptBuffer();
script.appendScript("updatePoint(")
.appendData(str1)
.appendScript(",")
.appendData (str2)
.appendScript(");");
// Push script out to clients viewing the page
Collection<ScriptSession> sessions =
ctx.getScriptSessionsByPage("/ebnms/index.eb?do=dwrtest");
logger.info ("jsp session size:" + sessions.size ());
// or
Collection<ScriptSession> sessions2 =
ctx.getAllScriptSessions ();
logger.info ("all session size:" + sessions2.size ());
for (ScriptSession session : sessions2) {
session.addScript(script);
}
}
return 0;
}
}
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 Logger logger = Logger.getLogger (NotifyClient.class.getName());
private ServletContext servletContext = null;
public void setServletContext( ServletContext servletContext )
{
this.servletContext = servletContext;
}
public int serviceUpdate (String str1, String str2) {
logger.info ("entered");
logger.info ("WebContext1"+servletContext);
ServerContext ctx = ServerContextFactory.get(servletContext );
// Generate JavaScript code to call client-side
// WebContext ctx = WebContextFactory.get();
logger.info ("WebContext"+ctx);
if (ctx != null) {
//String currentPage = ctx.getCurrentPage();
//logger.info ("current page:" + currentPage);
ScriptBuffer script = new ScriptBuffer();
script.appendScript("updatePoint(")
.appendData(str1)
.appendScript(",")
.appendData (str2)
.appendScript(");");
// Push script out to clients viewing the page
Collection<ScriptSession> sessions =
ctx.getScriptSessionsByPage("/ebnms/index.eb?do=dwrtest");
logger.info ("jsp session size:" + sessions.size ());
// or
Collection<ScriptSession> sessions2 =
ctx.getAllScriptSessions ();
logger.info ("all session size:" + sessions2.size ());
for (ScriptSession session : sessions2) {
session.addScript(script);
}
}
return 0;
}
}
另外,ScriptBuffer的appendScript方法是插入原始字串,appendData會根據(jù)參數(shù)類型做相應(yīng)轉(zhuǎn)換。