随笔-124  评论-194  文章-0  trackbacks-0
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会根据参数类型做相应转换。
posted on 2007-11-01 17:35 我爱佳娃 阅读(5185) 评论(3)  编辑  收藏 所属分类: AJAX

评论:
# re: DWR Reverse Ajax功能实践的要点 2007-11-02 10:41 | benson
谢谢楼主提供~~有机会试试长连接的应用。  回复  更多评论
  
# re: DWR Reverse Ajax功能实践的要点 2014-09-13 19:43 | zwl
logger.info ("WebContext1"+servletContext);  回复  更多评论
  
# re: DWR Reverse Ajax功能实践的要点 2014-09-13 19:44 | zwl
logger.info ("WebContext1"+servletContext);得到的值为空啊  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: