Heim >Web-Frontend >js-Tutorial >Umgekehrte Verwendung von Ajax
Dieses Mal werde ich Ihnen die umgekehrte Verwendung von Ajax vorstellen. Was sind die Vorsichtsmaßnahmen für die umgekehrte Verwendung von Ajax? Hier sind praktische Fälle.
Szenario 1: Wenn eine neue E-Mail vorliegt, wird auf der Webseite automatisch eine Aufforderungsnachricht angezeigt, ohne dass der Benutzer den Posteingang manuell aktualisieren muss.
Szenario 2: Nachdem das Mobiltelefon des Benutzers den QR-Code auf der Seite gescannt hat, springt die Seite automatisch weiter.
Szenario 3: Wenn jemand in einer Chatroom-ähnlichen Umgebung spricht, können alle angemeldeten Benutzer die Nachricht sofort sehen.
Im Vergleich zum herkömmlichen MVC-Modell, bei dem Anfragen vom Client initiiert und vom Server beantwortet werden müssen, kann die Verwendung von Reverse Ajax simulieren, dass der Server Ereignisse aktiv an den Client weiterleitet, um die Benutzererfahrung zu verbessern. In diesem Artikel wird die umgekehrte Ajax-Technologie in zwei Teilen erläutert, darunter: Comet und WebSocket. Der Artikel soll zeigen, wie die beiden oben genannten technischen Mittel implementiert werden. Die Anwendung in Struts2 oder SpringMVC wird nicht behandelt. Darüber hinaus verwendet die Konfiguration von Servlet auch Anmerkungen. Weitere Informationen finden Sie in anderen Materialien.
1. Comet (die beste Kompatibilitätsmethode)
Comet ist im Wesentlichen ein Konzept: die Möglichkeit, eine Verbindung vom Server zum Client herzustellen Daten. Bei einer Standard-HTTP-Ajax-Anfrage werden Daten an den Server gesendet. Reverse Ajax simuliert die Durchführung einer Ajax-Anfrage auf bestimmte Weise, sodass der Server Ereignisse so schnell wie möglich an den Client senden kann. Da normale HTTP-Anfragen häufig von Seitensprüngen begleitet werden und Push-Ereignisse erfordern, dass der Browser auf derselben Seite oder demselben Frame bleibt, kann die Implementierung von Comet nur über Ajax abgeschlossen werden.
Der Implementierungsprozess ist wie folgt: Wenn die Seite geladen wird, wird eine Ajax-Anfrage an den Server gesendet, und der Server erhält die Anfrage und speichert sie in einem Thread. sicherer Container (normalerweise für die Warteschlange). Gleichzeitig kann der Server weiterhin normal auf andere Anfragen reagieren. Wenn das Ereignis eintrifft, das gepusht werden muss, durchläuft der Server die Anforderungen im Container und löscht ihn, nachdem er die Antwort zurückgegeben hat. Dann erhalten alle Browser, die auf der Seite bleiben, die Antwort und senden erneut Ajax-Anfragen, wobei der obige Vorgang wiederholt wird.
<%@ 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>LongPolling</h1> <input type="text" id="message" /> <input type="button" id="btn" value="发送" /> </body> </html>
Uns ist aufgefallen, dass die von btn gesendete Anfrage eigentlich keiner Antwort bedarf. Der Schlüssel zum gesamten Prozess besteht darin, dass der Client den Server immer mit der Verbindung()-Anfrage versorgt. Die Serverseite muss diese asynchrone Antwortmethode zunächst unterstützen. Glücklicherweise bieten die meisten Servlet-Container bisher eine gute Unterstützung. Nehmen Sie Tomcat unten als Beispiel:
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 ist eine threadsichere Implementierung der Queue-Warteschlange, die hier als Container zum Speichern von Anforderungen verwendet wird. AsyncContext ist eine von Tomcat unterstützte asynchrone Umgebung, und verschiedene Server verwenden leicht unterschiedliche Objekte. Das von Jetty unterstützte Objekt ist Continuation. Die Anforderung, die die Übertragung abgeschlossen hat, muss die zugehörige Anforderung über context.complete() beenden und CONNECTIONS.remove(context) verwenden, um die Warteschlange zu löschen.
2. WebSocket (Unterstützung von HTML5)
Comet mit HTTP Long Polling ist der beste Weg, um die umgekehrte Ajax-Methode zuverlässig zu implementieren, weil alle Browser unterstützen dies mittlerweile.
WebSockets erschienen in HTML5 und sind eine neuere Reverse-Ajax-Technologie als Comet. WebSockets unterstützen einen bidirektionalen Vollduplex-Kommunikationskanal, der auch von vielen Browsern (Firefox, Google Chrome und Safari) unterstützt wird. Verbindungen werden über HTTP-Anfragen (auch WebSockets-Handshakes genannt) und einige spezielle Header hergestellt. Die Verbindung ist immer aktiv und Sie können Daten in JavaScript schreiben und empfangen, genau wie mit einem unformatierten TCP-Socket.
Starten Sie die WebSocket-URL, indem Sie ws:// oder wss:// (bei SSL) eingeben. Wie im Bild gezeigt:
Zunächst einmal: WebSockets werden nicht von allen Browsern gut unterstützt und der IE hält sich offensichtlich zurück. Wenn Sie diese Technologie verwenden möchten, müssen Sie daher die Nutzungsumgebung des Benutzers berücksichtigen. Wenn Ihr Projekt für das Internet gedacht ist oder Mobiltelefonbenutzer einschließt, rate ich jedem, zweimal darüber nachzudenken.
Zweitens: Die von WebSockets bereitgestellte Anfrage unterscheidet sich von einer normalen HTTP-Anfrage. Es handelt sich um eine Vollduplex-Kommunikation und ist immer aktiv (sofern Sie sie nicht deaktivieren). Dies bedeutet, dass Sie nicht jedes Mal, wenn Sie eine Antwort erhalten, erneut eine Anfrage an den Server senden müssen, was viele Ressourcen sparen kann.
<%@ 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>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) 等好处。更良好的用户体验也会带来新的商业契机。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
Das obige ist der detaillierte Inhalt vonUmgekehrte Verwendung von Ajax. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!