dwr 实现发布公告功能(服务器发送,客户端全部可以同时接收)

效果:服务器端发出消息,各个客户端及时接受消息。

1,要使用dwr的ajaxReverse 技术首先要在web.xml里给dwr的servlet加上下列参数配置:

<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>

2,服务器端代码:public class MyReverse {public void sendMes(String mes){ final String msg = mes;Browser.withAllSessionsFiltered(new ScriptSessionFilter() {public boolean match(ScriptSession session) {return true;}, new Runnable() {public void run() { Util.setValue("news", msg);//接收页面textarea的id}});}}

//以上是针对,每一个页面有textarea id为 news 的,都会自动获取,当然页面要开启反转,想要针对某个用户,请在scriptsessionFiter,写上方法;

//一下,是针对某个页面,有textarea id为 news 的,当然页面要开启反转(通过 wctx.getCurrentPage()获取你的页面,因为不同框架,不同页面的地址不一样,我的ssh就是/admin/ad!server,对应的是web-inf下的admin/ad/server.jsp页面)我觉得,就是填上跳转到某个页面的链接;

public void sendMes(String mes){  
System.out.println(mes);
final String msg = mes;
DefaultWebContext wctx = (DefaultWebContext) WebContextFactory.get(); // 这里是获取WebContext上下文
String currentPage = wctx.getCurrentPage();
System.out.println(currentPage);
Browser.withPage("/admin/ad!server", new Runnable() {
public void run() {
Util.setValue("news", msg);  //news 客户端jsp里面textarea的id
}
});

}



 3.dwr配置:

 <create javascript="myrevsrse" creator="new">
<param name="class" value="com.dwr.MyReverse"/>
</create>

 

3.服务端 (server.jsp用于发消息也就是管理员界面)

<html>
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<script type="text/javascript" src="dwr/interface/myrevsrse.js"></script>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<script type="text/javascript">
function sendnews(){
var new_content = ${'newcontent'}.value;
myrevsrse.sendMes(new_content);
}
</script>
</head>
<body>
<input type="text" name="newcontent">
<input type = "button" value="发消息" οnclick="sendnews()"/>
</body>

  客户端:

 

<html>
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<head>
<<script type="text/javascript">
</script>
</head>
<body οnlοad="dwr.engine.setActiveReverseAjax(true);">
<textarea rows="20" cols="20" id="news"></textarea>
</body>
</html>

 测试:

我们打开一个服务端,2和客户端, 

 

服务端发出消息,点击发消息后,个客户端将同步显示服务端发出的消息。

 

 

 通过源代码看看情况:(个人见解,希望大家指导和讨论):
   首先看看client端onload中执行的dwr方法:οnlοad="dwr.engine.setActiveReverseAjax(true); 此方法鉴于源代码:
    org.directwebremoting.ui.dwr.Engine,方法内容:

 

/**
     * Does DWR poll the server for updates? (Default: false)
     * 
@param activeReverseAjax True/False to turn RA on/off
     * 
@see <a href="http://getahead.org/dwr/browser/engine/options">Options documentation</a>
     
*/

     public  static  void setActiveReverseAjax( boolean activeReverseAjax)
     {
        ScriptBuffer script = new ScriptBuffer();
        script.appendScript("dwr.engine.setActiveReverseAjax(")
              .appendData(activeReverseAjax)
              .appendScript(");");
        ScriptSessions.addScript(script);
    }

接着会调用:

Collection<ScriptSession> sessions = Browser.getTargetSessions();
                 for (ScriptSession scriptSession : sessions)
                 {
                    scriptSession.addScript(script);
                }

其中Browser.getTargetSessions();是这样说的:

  /**
     * This method discovers the sessions that are currently being targeted
     * by browser updates.
     * <p>
     * It will generally only be useful to authors of reverse ajax UI proxy
     * APIs. Using it directly may cause scaling problems
     * 
@return The list of current browser windows.
     
*/

     public  static Collection<ScriptSession> getTargetSessions()
     {
        TaskDispatcher taskDispatcher = TaskDispatcherFactory.get();
        Collection<ScriptSession> sessions = taskDispatcher.getTargetSessions();
        if (sessions != null)
        {
            return sessions;
        }


        WebContext webContext = WebContextFactory.get();
        if (webContext != null)
        {
            sessions = new ArrayList<ScriptSession>();
            sessions.add(webContext.getScriptSession());
            return sessions;
        }


        throw new IllegalStateException("No current UI to manipulate. See org.directwebremoting.Browser to set one.");
    }

这个方法只对reverse代理有用,直接使用它可能会有问题,

   这里将看到WebContent 这个是关键:这里记录了client端连接的信息,而最重要的当然是session和response,最终服务端信息是同过response的PrintWriter来输出到客户端,而实际上dwrServlet在处理requst的时候调用了这个类,调用内容看下代码:
 

@Override
     public  void doPost(HttpServletRequest request, HttpServletResponse response)  throws IOException, ServletException
     {
        try
        {
            webContextBuilder.engageThread(container, request, response);

            UrlProcessor processor = container.getBean(UrlProcessor.class);
            processor.handle(request, response);
        }

        finally
        {
            webContextBuilder.disengageThread();
        }

    }


其中的ebContextBuilder.engageThread(container, request, response);正式调用了这个类:
 

  public  void engageThread(Container container, HttpServletRequest request, HttpServletResponse response)
     {
        try
        {
            ServletConfig servletConfig = container.getBean(ServletConfig.class);
            ServletContext servletContext = container.getBean(ServletContext.class);

            WebContext ec = new DefaultWebContext(container, request, response, servletConfig, servletContext);
            user.set(ec);
        }

        catch (Exception ex)
        {
            log.fatal("Failed to create an ExecutionContext", ex);
        }

    }
通过webcontext将我们的请求信息维持在服务端,
   具体下面的过程的大意就是 通过过滤所有scriptsession 是否含有dwr.engine.setActiveReverseAjax(true); 信息 并通过response发出服务端信息。
本文转自:
感谢 http://www.blogjava.net/freeman1984/archive/2009/11/19/302961.html 的无私奉献,这是我研究的demo;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值