這篇文章主要介紹了反向Ajax 30分鐘快速掌握的相關資料,需要的朋友可以參考下
場景1:當有新郵件的時候,網頁自動彈出提示信息而無需用戶手動的刷新收件匣。
場景2:當使用者的手機掃描完成頁面中的二維碼以後,頁面會自動跳轉。
場景3:在類似聊天室的環境中有任何人發言,所有登入使用者都可以即時看見訊息。
與傳統的MVC模型請求必須從客戶端發起由伺服器回應相比,使用反向Ajax能夠模擬伺服器端主動向客戶端推送事件從而提高使用者體驗。本文將分成兩個部分討論反向Ajax技術,包括:Comet和WebSocket。文章旨在示範如何實現以上兩種技術手段,Struts2或SpringMVC中的應用並未涉及。此外,Servlet的配置也採用註解的方式,相關知識大家可以參考其它資料。
一、Comet(最佳的相容手段)
Comet本質上則是這樣的概念:能夠從伺服器端向客戶端發送資料。在一個標準的 HTTP Ajax 請求中,資料是發送給伺服器端的,反向 Ajax 以某些特定的方式來模擬發出一個 Ajax 請求,這樣的話,伺服器就可以盡可能快地向客戶端發送事件。由於普通HTTP請求往往會伴隨頁面的跳轉,而推播事件則需要瀏覽器停留在同一個頁面或框架下,因此Comet的實作只能夠透過Ajax來完成。
它的實作過程如下:頁面載入的時候隨即向伺服器發送一條Ajax請求,伺服器端取得請求並將它保存在一個執行緒安全的容器中(通常為隊列)。同時伺服器端仍然可以正常回應其他請求。當需要推送的事件到來的時候,伺服器遍歷容器中的請求在傳回應答後刪除。於是所有停留在頁面中的瀏覽器都會獲得該應答,並再次發送Ajax請求,重複上述過程。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE html> <html lang="en"> <base href="<%=basePath%>"> <head> <title>WebSocket</title> <script type="text/javascript" src="static/jquery-1.9.1.min.js"></script> <script type="text/javascript"> $(function() { connect(); $("#btn").click(function() { var value = $("#message").val(); $.ajax({ url : "longpolling?method=onMessage&msg=" + value, cache : false, dataType : "text", success : function(data) { } }); }); }); function connect() { $.ajax({ url : "longpolling?method=onOpen", cache : false, dataType : "text", success : function(data) { connect(); alert(data); } }); } </script> </head> <body> <h1 id="LongPolling">LongPolling</h1> <input type="text" id="message" /> <input type="button" id="btn" value="发送" /> </body> </html>
我們注意到,由btn發送的請求其實並不需要取得回應。整個過程的關鍵是需要客戶端始終讓伺服器保持connect()的請求。而伺服器端首先需要支援這種非同步的回應方式,幸運的是目前為止絕大部分的Servlet容器都已經提供了良好的支援。以下以Tomcat為例:
package servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(value="/longpolling", asyncSupported=true) public class Comet extends HttpServlet { private static final Queue<AsyncContext> CONNECTIONS = new ConcurrentLinkedQueue<AsyncContext>(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getParameter("method"); if (method.equals("onOpen")) { onOpen(req, resp); } else if (method.equals("onMessage")) { onMessage(req, resp); } } private void onOpen(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { AsyncContext context = req.startAsync(); context.setTimeout(0); CONNECTIONS.offer(context); } private void onMessage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String msg = req.getParameter("msg"); broadcast(msg); } private synchronized void broadcast(String msg) { for (AsyncContext context : CONNECTIONS) { HttpServletResponse response = (HttpServletResponse) context.getResponse(); try { PrintWriter out = response.getWriter(); out.print(msg); out.flush(); out.close(); context.complete(); CONNECTIONS.remove(context); } catch (IOException e) { e.printStackTrace(); } } } }
ConcurrentLinkedQueue是Queue佇列的一個線程安全實現,這裡使用它來作為保存請求的容器。 AsyncContext是Tomcat支援的非同步環境,不同的伺服器使用的物件也略有不同。 Jetty支援的物件是Continuation。完成了廣播的請求需要透過context.complete()將相關請求結束,並使用CONNECTIONS.remove(context)刪除佇列。
二、WebSocket(來自HTML5的支援)
使用HTTP 長輪詢的Comet 是可靠地實現反向Ajax 的最佳方式,因為現在所有瀏覽器都提供了這方面的支援。
WebSockets 在 HTML5 中出現,是比 Comet 更新的反向 Ajax 技術。 WebSockets 支援雙向、全雙工通訊頻道,許多瀏覽器(Firefox、Google Chrome 和 Safari)也支援它。連線透過 HTTP 請求(也稱為 WebSockets 握手)和一些特殊的標頭 (header)。連線一直處於啟動狀態,您可以用 JavaScript 編寫和接收數據,就像您使用原始 TCP 套接字一樣。
透過輸入 ws:// 或 wss://(在 SSL 上)啟動 WebSocket URL。如圖:
首先:WebSockets並非在所有瀏覽器上都能獲得良好的支持,顯然IE又拖了後腿。因此當你打算使用這項技術之前必須考慮到用戶的使用環境,如果你的專案面向的是互聯網或包括手機端用戶,奉勸大家三思。
其次:WebSockets提供的請求區別於普通的HTTP請求,它是一種全雙工通訊且始終處於啟動狀態(如果你不去關閉它的話)。這意味著你不用每次獲得應答後再次向伺服器發送請求,這樣可以節省大量的資源。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; String ws = "ws://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE html> <html lang="en"> <base href="<%=basePath%>"> <head> <title>WebSocket</title> <script type="text/javascript" src="static/jquery-1.9.1.min.js"></script> <script type="text/javascript"> $(function() { var websocket = null; if ("WebSocket" in window){ websocket = new WebSocket("<%=ws%>websocket"); } else { alert("not support"); } websocket.onopen = function(evt) { } websocket.onmessage = function(evt) { alert(evt.data); } websocket.onclose = function(evt) { } $("#btn").click(function() { var text = $("#message").val(); websocket.send(text); }); }); </script> </head> <body> <h1 id="WebSocket">WebSocket</h1> <input type="text" id="message" /> <input type="button" id="btn" value="发送"/> </body> </html>
JQuery對WebSocket還未提供更良好的支持,因此我們必須使用Javascript來編寫部分程式碼(好在並不複雜)。並且打部分常見的伺服器都可以支援ws請求,以Tomcat為例。在6.0版本中WebSocketServlet物件已經被標註為@java.lang.Deprecated,7.0以後的版本支援jsr365提供的實現,因此你必須使用註解來完成相關配置。
package servlet; import java.io.IOException; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/websocket") public class WebSocket { private static final Queue<WebSocket> CONNECTIONS = new ConcurrentLinkedQueue<WebSocket>(); private Session session; @OnOpen public void onOpen(Session session) { this.session = session; CONNECTIONS.offer(this); } @OnMessage public void onMessage(String message) { broadcast(message); } @OnClose public void onClose() { CONNECTIONS.remove(this); } private synchronized void broadcast(String msg) { for (WebSocket point : CONNECTIONS) { try { point.session.getBasicRemote().sendText(msg); } catch (IOException e) { CONNECTIONS.remove(point); try { point.session.close(); } catch (IOException e1) { } } } } }
三、總結(從請求到推送)
#在傳統通訊方案中,如果系統 A 需要係統 B 中的信息,它會向系統 B 發送一個請求。系統 B 將處理請求,而係統 A 會等待回應。處理完成後,會將回應傳回系統 A。在同步 通訊模式下,資源使用效率比較低,這是因為等待回應時會浪費處理時間。
在非同步 模式下,系統 A 將訂閱它想從系統 B 中取得的資訊。然後,系統 A 可以向系統 B 發送通知,也可以立即傳回訊息,同時,系統 A 可以處理其他事務。這個步驟是可選的。在事件驅動應用程式中,通常不必要求其他系統發送事件,因為您不知道這些事件是什麼。在系統 B 發布回應之後,系統 A 會立即收到該回應。
Web 框架過去通常依賴傳統 “請求-回應” 模式,該模式會導致頁面重新整理。隨著 Ajax、Reverse Ajax 以及 WebSocket 的出現,現在可以將事件驅動架構的概念輕鬆應用於 Web,獲得去耦合、可擴展性和反應性 (reactivity) 等好處。更良好的使用者體驗也會帶來新的商業契機。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
以上是反向Ajax 30分鐘快速掌握的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版
中文版,非常好用

WebStorm Mac版
好用的JavaScript開發工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)