DWR Reverse Ajax功能实践的要点

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


首先,说一下代码的组织和声明。
将使用到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 >


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

< 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接口,下面是完整代码:

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



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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值