反向Ajax之非同步Servlet

壹頁書發表於2013-12-27
實現反向Ajax功能,除了WebSocket之外,還有Servlet3.0提供的非同步Servlet.

實驗透過Servlet3.0的非同步Servlet實現獲取伺服器端JVM資訊的功能。
http://blog.itpub.net/29254281/viewspace-1064838/

1.非同步Servlet程式設定asyncSupported為true,並返回組裝的JS程式碼。

  1. import java.io.IOException;
  2. import java.io.PrintWriter;
  3. import java.util.Date;
  4. import java.util.Queue;
  5. import java.util.concurrent.ConcurrentLinkedQueue;
  6. import java.util.concurrent.Executors;
  7. import java.util.concurrent.ScheduledExecutorService;
  8. import java.util.concurrent.TimeUnit;

  9. import javax.servlet.AsyncContext;
  10. import javax.servlet.AsyncEvent;
  11. import javax.servlet.AsyncListener;
  12. import javax.servlet.ServletException;
  13. import javax.servlet.annotation.WebServlet;
  14. import javax.servlet.http.HttpServlet;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.servlet.http.HttpServletResponse;

  17. @WebServlet(urlPatterns = { "/ac.do" }, asyncSupported = true)
  18. public class InitServlet extends HttpServlet implements Runnable {
  19.     Queue<AsyncContext> queue = new ConcurrentLinkedQueue<AsyncContext>();

  20.     ScheduledExecutorService singleThread = Executors.newSingleThreadScheduledExecutor();
  21.     {
  22.         singleThread.scheduleWithFixedDelay(this, 3, 3, TimeUnit.SECONDS);
  23.     }

  24.     @Override
  25.     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  26.         doGet(req, resp);
  27.     }

  28.     @Override
  29.     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  30.         final AsyncContext ac = req.startAsync();
  31.         ac.setTimeout(10 * 60 * 1000);
  32.         ac.addListener(new AsyncListener() {
  33.             public void onComplete(AsyncEvent event) throws IOException {
  34.                 queue.remove(ac);
  35.             }

  36.             public void onTimeout(AsyncEvent event) throws IOException {
  37.                 queue.remove(ac);
  38.             }

  39.             public void onError(AsyncEvent event) throws IOException {
  40.                 queue.remove(ac);
  41.             }

  42.             public void onStartAsync(AsyncEvent event) throws IOException {
  43.             }
  44.         });
  45.         queue.add(ac);
  46.     }

  47.     private String getJVMInfo() {
  48.         long useMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
  49.         useMemory = useMemory / 1024;
  50.         return "已用記憶體:" + String.valueOf(useMemory) + "K";
  51.     }

  52.     /**
  53.      * 這個函式太重要了! 返回JS程式碼執行.它呼叫父視窗的update方法
  54.      */
  55.     private String htmlEscape(String message) {
  56.         return ";
  57.     }

  58.     @Override
  59.     public void run() {
  60.         System.out.println("傳送廣播通知");
  61.         String data = "廣播通知\n" + new Date() + "\n" + getJVMInfo();
  62.         for (AsyncContext ac : queue) {
  63.             try {
  64.                 ac.getResponse().setContentType("text/html;charset=UTF-8");
  65.                 PrintWriter writer = ac.getResponse().getWriter();
  66.                 writer.println(htmlEscape(data));
  67.                 writer.flush();
  68.             } catch (IOException e) {
  69.                 queue.remove(ac);
  70.                 e.printStackTrace();
  71.             }

  72.         }
  73.     }
  74. }
2.前臺透過隱藏的iframe傳輸資訊

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <title>WebSocket</title>
  6. <script type="text/javascript"
  7.     src=""></script>
  8. <script type="text/javascript">
  9.     $(document).ready(function() {
  10.         var url = './ac.do';
  11.         $('#comet-frame')[0].src = url;
  12.     });

  13.     function update(data) {
  14.         $('#content').html(data);
  15.     }
  16. </script>
  17. </head>
  18. <body>
  19.     <div id="content"></div>
  20.     <iframe id="comet-frame" style="display: none;"></iframe>
  21. </body>
  22. </html>
參考:
http://www.ibm.com/developerworks/cn/java/j-lo-comet/


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1065151/,如需轉載,請註明出處,否則將追究法律責任。

相關文章