Maison > interface Web > js tutoriel > le corps du texte

Utilisation inversée d'Ajax

php中世界最好的语言
Libérer: 2018-04-03 17:48:18
original
1381 Les gens l'ont consulté

Cette fois je vais vous présenter l'utilisation inversée d'Ajax. Quelles sont les précautions pour l'utilisation inversée d'Ajax Voici des cas pratiques, jetons un oeil.

Scénario 1 : lorsqu'il y a un nouvel e-mail, la page Web affiche automatiquement un message d'invite sans que l'utilisateur ait à actualiser manuellement la boîte de réception.

Scénario 2 : Une fois que le téléphone mobile de l'utilisateur a scanné le code QR sur la page, la page sautera automatiquement.

Scénario 3 : Si quelqu'un parle dans un environnement de type salon de discussion, tous les utilisateurs connectés peuvent voir le message immédiatement.

Par rapport au modèle MVC traditionnel où les requêtes doivent être initiées par le client et auxquelles le serveur doit répondre, l'utilisation d'Ajax inversé peut simuler le serveur qui envoie activement des événements au client pour améliorer l'expérience utilisateur. Cet article abordera la technologie Ajax inversée en deux parties, notamment : Comet et WebSocket. L'article vise à démontrer comment implémenter les deux moyens techniques ci-dessus, et l'application dans Struts2 ou SpringMVC n'est pas couverte. De plus, la configuration de Servlet utilise également des annotations. Vous pouvez vous référer à d'autres documents pour des connaissances connexes.

1. Comet (la meilleure méthode de compatibilité)

Comet est essentiellement un concept : pouvoir se connecter depuis le serveur au client envoie données. Dans une requête HTTP Ajax standard, les données sont envoyées au serveur. Reverse Ajax simule l'exécution d'une requête Ajax d'une manière spécifique, afin que le serveur puisse envoyer des événements au client le plus rapidement possible. Étant donné que les requêtes HTTP ordinaires sont souvent accompagnées de sauts de page et que les événements push nécessitent que le navigateur reste sur la même page ou cadre, l'implémentation de Comet ne peut être réalisée que via Ajax.

Son processus de mise en œuvre est le suivant : lorsque la page est chargée, une requête Ajax est envoyée au serveur, et le serveur récupère la requête et l'enregistre dans un thread- conteneur sécurisé (généralement pour la file d'attente). Dans le même temps, le serveur peut toujours répondre normalement aux autres demandes. Lorsque l'événement qui doit être poussé arrive, le serveur parcourt les requêtes dans le conteneur et le supprime après avoir renvoyé la réponse. Ensuite, tous les navigateurs restant sur la page recevront la réponse et enverront à nouveau les requêtes Ajax, en répétant le processus ci-dessus.

<%@ 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>
Copier après la connexion

Nous avons remarqué que la demande envoyée par btn n'a pas réellement besoin de réponse. La clé de tout le processus est que le client garde toujours le serveur connecté () à la demande. Le côté serveur doit d'abord prendre en charge cette méthode de réponse asynchrone. Heureusement, la plupart des conteneurs de servlets ont jusqu'à présent fourni un bon support. Prenons Tomcat comme exemple ci-dessous :

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();
}
}
}
}
Copier après la connexion

ConcurrentLinkedQueue est une implémentation thread-safe de la file d'attente Queue, qui est utilisée ici comme conteneur pour enregistrer les requêtes. AsyncContext est un environnement asynchrone pris en charge par Tomcat et différents serveurs utilisent des objets légèrement différents. L'objet pris en charge par Jetty est Continuation. La requête qui a terminé la diffusion doit mettre fin à la requête associée via context.complete() et utiliser CONNECTIONS.remove(context) pour supprimer la file d'attente.

2. WebSocket (prise en charge de HTML5)

Comet utilisant l'interrogation longue HTTP est le meilleur moyen d'implémenter de manière fiable la méthode Ajax inversée, car tout les navigateurs prennent désormais en charge cela.

Les WebSockets sont apparus en HTML5 et sont une technologie Ajax inversée plus récente que Comet. Les WebSockets prennent en charge un canal de communication bidirectionnel en duplex intégral, et de nombreux navigateurs (Firefox, Google Chrome et Safari) le prennent également en charge. Les connexions sont établies via des requêtes HTTP (également appelées poignées de main WebSockets) et certains en-têtes spéciaux. La connexion est toujours active et vous pouvez écrire et recevoir des données en JavaScript comme vous le feriez avec un socket TCP brut.

Démarrez l'URL WebSocket en saisissant ws:// ou wss:// (sur SSL). Comme le montre l'image :

Tout d'abord : les WebSockets ne sont pas bien pris en charge sur tous les navigateurs, et évidemment IE se retient. Par conséquent, lorsque vous envisagez d'utiliser cette technologie, vous devez tenir compte de l'environnement d'utilisation de l'utilisateur. Si votre projet concerne Internet ou inclut des utilisateurs de téléphones mobiles, je conseille à chacun d'y réfléchir à deux fois.

Deuxièmement : la requête fournie par WebSockets est différente de la requête HTTP ordinaire. Il s'agit d'une communication full-duplex et est toujours active (si vous ne la désactivez pas). Cela signifie que vous n'avez pas besoin de renvoyer une requête au serveur à chaque fois que vous recevez une réponse, ce qui peut économiser beaucoup de ressources.

<%@ 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>
Copier après la connexion

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) {
}
}
}
}
}
Copier après la connexion

三、总结(从请求到推送)

在传统通信方案中,如果系统 A 需要系统 B 中的信息,它会向系统 B 发送一个请求。系统 B 将处理请求,而系统 A 会等待响应。处理完成后,会将响应发送回系统 A。在同步 通信模式下,资源使用效率比较低,这是因为等待响应时会浪费处理时间。

在异步 模式下,系统 A 将订阅它想从系统 B 中获取的信息。然后,系统 A 可以向系统 B 发送一个通知,也可以立即返回信息,与此同时,系统 A 可以处理其他事务。这个步骤是可选的。在事件驱动应用程序中,通常不必请求其他系统发送事件,因为您不知道这些事件是什么。在系统 B 发布响应之后,系统 A 会立即收到该响应。

Web 框架过去通常依赖传统 “请求-响应” 模式,该模式会导致页面刷新。随着 Ajax、Reverse Ajax 以及 WebSocket 的出现,现在可以将事件驱动架构的概念轻松应用于 Web,获得去耦合、可伸缩性和反应性 (reactivity) 等好处。更良好的用户体验也会带来新的商业契机。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Ajax怎么实现智能提示关联词搜索

Ajax请求响应中打开新窗口被拦截应该如何处理

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal