瘋狂

          STANDING ON THE SHOULDERS OF GIANTS
          posts - 481, comments - 486, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          DWR ajaxReverse demo 和理解

          Posted on 2009-11-19 18:28 瘋狂 閱讀(4057) 評論(0)  編輯  收藏 所屬分類: java 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){
          send("系統消息:"+mes);
          }
          public void send(final String output) {
          String page = ServerContextFactory.get().getContextPath() + "/client.jsp";
          Browser.withPage(page, new Runnable() {
          public void run() {
          Util.setValue("news", output);  //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="發消息" onclick="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 onload="dwr.engine.setActiveReverseAjax(true);">
          <textarea rows="20" cols="20" id="news"></textarea>
          </body>
          </html>

           測試:

          我們打開一個服務端,2和客戶端, 

           

          服務端發出消息,點擊發消息后,個客戶端將同步顯示服務端發出的消息。

           

           

           通過源代碼看看情況:(個人見解,希望大家指導和討論):
             首先看看client端onload中執行的dwr方法:onload="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發出服務端信息。
            
          時間關系歡迎大家繼續討論!
          主站蜘蛛池模板: 冕宁县| 临泽县| 华宁县| 龙州县| 西华县| 乡宁县| 汽车| 东平县| 哈密市| 兰溪市| 荔波县| 灵台县| 安西县| 兴隆县| 辽阳市| 读书| 汉阴县| 龙川县| 灵璧县| 四平市| 石家庄市| 北安市| 平罗县| 且末县| 公安县| 宣威市| 宁南县| 固始县| 当阳市| 南通市| 天柱县| 讷河市| 当雄县| 陈巴尔虎旗| 沂源县| 贞丰县| 玉田县| 庆元县| 孝感市| 鹤峰县| 广安市|