Maison >interface Web >js tutoriel >Discussion pratique sur le Web et WebSocket

Discussion pratique sur le Web et WebSocket

伊谢尔伦
伊谢尔伦original
2017-01-23 14:22:181374parcourir

Pourquoi le Web en temps réel est-il si important ? Nous vivons dans un monde en temps réel, c’est pourquoi l’état ultime et le plus naturel du Web devrait également être le temps réel. Les utilisateurs ont besoin de communications, de données et de recherches en temps réel. Nos besoins en informations en temps réel sur Internet sont également de plus en plus élevés. Si les informations ou les messages sont mis à jour après un délai de plusieurs minutes, cela devient tout simplement insupportable. Aujourd'hui, de nombreuses grandes entreprises (telles que Google, Facebook et Twitter) ont commencé à s'intéresser au Web en temps réel et à proposer des services en temps réel. Le Web en temps réel sera l'un des sujets les plus brûlants à l'avenir.

L'histoire du développement du Web en temps réel

Le Web traditionnel est basé sur le modèle requête/réponse HTTP : le client demande une nouvelle page, et le serveur envoie le contenu au client, le client doit renvoyer la demande lors de la demande d'une autre page. Plus tard, quelqu'un a proposé AJAX, qui rendait l'expérience de la page plus « dynamique » et pouvait lancer des requêtes vers le serveur en arrière-plan. Cependant, si le serveur dispose de davantage de données à transmettre au client, il n'est pas possible d'envoyer directement les données du serveur au client une fois la page chargée. Les données en temps réel ne peuvent pas être « poussées » vers le client.
Afin de résoudre ce problème, de nombreuses solutions ont été proposées. La solution la plus simple (force brute) consiste à utiliser le polling : demander de nouvelles données au serveur de temps en temps. Cela donne l'impression que l'application est en temps réel pour l'utilisateur. En fait, cela entraînera des problèmes de latence et de performances, car le serveur doit gérer un grand nombre de demandes de connexion chaque seconde, et chaque demande aura une négociation à trois voies TCP et des informations d'en-tête HTTP. Bien que le sondage soit encore utilisé aujourd’hui dans de nombreuses applications, il ne s’agit pas de la solution la plus idéale.
Plus tard, avec l'introduction de la technologie Comet, de nombreuses solutions plus avancées ont vu le jour. Ces solutions techniques incluent le frame permanent (forever frame), le flux XHR (xhr-multipart), le fichier html et l'interrogation longue. Une interrogation longue signifie que le client initie une connexion XHR au serveur. Cette connexion n'est jamais fermée et la connexion est toujours suspendue pour le client. Lorsque le serveur dispose de nouvelles données, il envoie rapidement une réponse au client, puis ferme la connexion. Ensuite, l'ensemble du processus est répété et on obtient ainsi un « push serveur ».
La technologie Comet est une technologie de hack non standard. De ce fait, la compatibilité des navigateurs devient un problème. Tout d’abord, le problème de performances ne peut pas être résolu. Chaque connexion initiée au serveur transporte des informations d’en-tête HTTP complètes, ce qui constituera un problème épineux si votre application nécessite une latence très faible. Bien sûr, ce n’est pas qu’il y ait quelque chose qui ne va pas avec Comet lui-même, car Comet est notre seul choix jusqu’à ce qu’il y ait d’autres alternatives.
Les plug-ins de navigateur (tels que Flash) et Java sont également utilisés pour implémenter le push serveur. Ils peuvent établir des connexions socket directement avec le serveur basées sur TCP, ce qui est très approprié pour transmettre des données en temps réel au client. Le problème est que ces plug-ins ne sont pas installés sur tous les navigateurs et qu'ils sont souvent bloqués par les pare-feu, notamment sur les réseaux d'entreprise.
Désormais, la spécification HTML5 nous a préparé une alternative. Cependant, cette spécification est un peu en avance sur son temps. De nombreux navigateurs ne la prennent pas encore en charge, en particulier IE. Elle n'est pas d'une grande aide pour de nombreux développeurs actuels. Étant donné que la plupart des navigateurs n'ont pas encore implémenté HTML5 WebSocket, la meilleure solution reste de le faire. utilisez Comète.

WebSocket passé et présent

Comme nous le savons tous, le processus d'interaction des applications Web est généralement le suivant : le client envoie une requête via le navigateur, le serveur reçoit la requête, la traite et renvoie le résultat. au client, et le client parcourt Les informations sont présentées par le serveur. Ce mécanisme est acceptable pour les applications où les changements d'informations ne sont pas particulièrement fréquents, mais il est insuffisant pour les applications avec des exigences élevées en temps réel et une concurrence massive. Tendance de développement en plein essor de l'Internet mobile dans l'industrie, la concurrence élevée est étroitement liée aux utilisateurs. La réponse en temps réel est un problème auquel les applications Web sont souvent confrontées, comme les informations en temps réel sur les titres financiers, l'acquisition de localisation géographique dans les applications de navigation Web, -time message push sur les réseaux sociaux, etc.

Le modèle de demande-réponse traditionnel Le développement Web utilise généralement des solutions de communication en temps réel pour traiter de tels scénarios commerciaux. Les plus courants sont :

Le principe est simple et facile à comprendre, c'est-à-dire que le client maintient la synchronisation des données entre le client et le serveur en envoyant des requêtes au serveur sous la forme de requêtes fréquentes à certains intervalles. Le problème est évident. Lorsque le client envoie des requêtes au serveur à une fréquence fixe, les données sur le serveur peuvent ne pas être mises à jour, ce qui entraîne de nombreuses requêtes inutiles, un gaspillage de bande passante et une faible efficacité.

Basé sur Flash, Adobe Flash implémente l'échange de données via son propre Socket, puis utilise Flash pour exposer les interfaces correspondantes pour les appels JavaScript afin d'obtenir une transmission en temps réel. Cette méthode est plus efficace que l'interrogation et, comme Flash a un taux d'installation élevé, elle offre un large éventail de scénarios d'application. Cependant, la prise en charge de Flash sur les terminaux Internet mobiles n'est pas bonne. Il n'y a pas de Flash dans le système IOS. Bien qu'Android prenne en charge Flash, l'effet d'utilisation réel n'est pas satisfaisant et les exigences de configuration matérielle de l'appareil mobile sont relativement élevées. En 2012, Adobe annonçait officiellement qu'il ne supporterait plus le système Android 4.1, annonçant la mort de Flash sur les terminaux mobiles.

Comme le montre ce qui précède, le modèle Web traditionnel rencontrera des goulots d'étranglement insurmontables lorsqu'il sera confronté à des exigences élevées de concurrence et de temps réel. Nous avons besoin d'un mécanisme de communication bidirectionnel efficace et économe en énergie pour garantir une communication réelle. transmission de données temporelles. Dans ce contexte, WebSocket, connu sous le nom de Web TCP, est né sur la base de la spécification HTML5.

Au début, HTML5 ne formait pas une spécification unifiée dans l'industrie. Différents navigateurs et fabricants de serveurs d'applications avaient différentes implémentations similaires, comme le MQTT d'IBM, le framework open source Comet, etc. Jusqu'en 2014, HTML5 l'était. adopté par IBM, Microsoft, Avec la promotion et la coopération de géants tels que Google, la poussière s'est finalement mise en place et elle a été officiellement mise en œuvre à partir d'un projet dans une véritable spécification standard. Divers fabricants de serveurs d'applications et de navigateurs ont progressivement commencé à s'unifier. Le protocole WebSocket a également été implémenté dans JavaEE7, de sorte que WebSocket All client et serveur soit complet, les lecteurs peuvent vérifier la spécification HTML5 et se familiariser avec la nouvelle spécification du protocole HTML et la prise en charge de WebSocket.

Mécanisme WebSocket

Ce qui suit est une brève introduction au principe et au mécanisme de fonctionnement de WebSocket.

WebSocket est un nouveau protocole en HTML5. Il réalise une communication en duplex intégral entre le navigateur et le serveur, ce qui permet de mieux économiser les ressources et la bande passante du serveur et d'obtenir une communication en temps réel. Il est construit sur TCP et transmet les données via TCP comme HTTP. Cependant, sa plus grande différence avec HTTP est :

WebSocket est un protocole de communication bidirectionnel. Après avoir établi une connexion, le serveur WebSocket et l'agent navigateur/client peuvent activement s'envoyer ou recevoir des données, tout comme

WebSocket l'exige ; Semblable à TCP, le client et le serveur sont connectés via une poignée de main et ils ne peuvent communiquer entre eux qu'une fois la connexion établie.

L'interaction entre le client HTTP traditionnel et le serveur en mode non-WebSocket est illustrée dans la figure ci-dessous :

Figure 1. Diagramme d'interaction client-serveur de réponse à une requête HTTP traditionnelle

Discussion pratique sur le Web et WebSocket

L'interaction entre le client et le serveur à l'aide du mode WebSocket est la suivante :

Figure 2. Diagramme d'interaction client-serveur de réponse à la demande WebSocket

Discussion pratique sur le Web et WebSocket

Fig. La comparaison montre que, comparé au mode HTTP traditionnel où chaque requête-réponse nécessite que le client établisse une connexion avec le serveur, WebSocket est un mode de communication TCP à connexion longue similaire à Socket. Une fois la connexion WebSocket établie, les données suivantes sont transmises sous forme de séquence de trames. Avant que le client ne déconnecte la connexion WebSocket ou que le serveur ne se déconnecte, le client et le serveur n'ont pas besoin de relancer la demande de connexion. Dans le cas d'une concurrence massive et d'une charge d'interaction élevée entre le client et le serveur, cela permet d'économiser considérablement la consommation des ressources de bande passante du réseau et présente des avantages évidents en termes de performances. De plus, le client envoie et reçoit des messages sur la même connexion persistante, en temps réel. L'avantage sexuel est évident.

Regardons la différence entre la communication WebSocket et le HTTP traditionnel à travers les messages interactifs entre le client et le serveur :

Côté client, le nouveau WebSocket instancie un nouvel objet client WebSocket. Connectez-vous à l'URL WebSocket du serveur similaire à ws://votredomaine:port/chemin. L'objet client WebSocket sera automatiquement analysé et reconnu comme une requête WebSocket, se connectant ainsi au port du serveur et effectuant le processus de prise de contact entre les deux parties. le format des données envoyées par le client est similaire :

Liste 1.Message de connexion client WebSocket

GET /webfin/websocket/ HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: http://localhost:8080
Sec-WebSocket-Version: 13

Comme vous pouvez le constater, le message de connexion WebSocket initié par le client est similaire au message HTTP traditionnel. La valeur du paramètre "Upgrade: websocket" indique qu'il s'agit d'une requête de type WebSocket, et "Sec-WebSocket-". Key" est envoyé par le client WebSocket. Un texte chiffré codé en base64 nécessite que le serveur renvoie une réponse chiffrée correspondante "Sec-WebSocket-Accept", sinon le client générera une erreur "Erreur lors de la prise de contact WebSocket" et fermera la connexion.

Le format de données renvoyé par le serveur après réception du message est similaire :

Listing 2. Message de réponse du serveur WebSocket

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

"Sec-WebSocket-Accept" Le La valeur est calculée par le serveur en utilisant la même clé que le client et renvoyée au client. "HTTP/1.1 101 Switching Protocols" signifie que le serveur accepte la connexion client du protocole WebSocket. Après ce traitement demande-réponse, le client. La négociation de connexion WebSocket côté serveur réussit et la communication TCP ultérieure peut être effectuée. Les lecteurs peuvent se référer à la pile de protocoles WebSocket pour découvrir des formats de données interactifs plus détaillés entre le client et le serveur WebSocket.

En termes de développement, l'API WebSocket est également très simple. Il suffit d'instancier WebSocket et de créer une connexion. Ensuite, le serveur et le client peuvent s'envoyer et répondre à des messages dans l'implémentation de WebSocket. et la section d'analyse de cas ci-dessous, vous pouvez voir l'API WebSocket détaillée et la mise en œuvre du code.

Implémentation WebSocket

Comme mentionné ci-dessus, l'implémentation de WebSocket est divisée en deux parties : le client et le serveur. Le client (généralement un navigateur) émet une demande de connexion WebSocket et le serveur. répond. Implémentation Une action similaire à la prise de contact TCP, formant ainsi un long canal HTTP de connexion rapide entre le client du navigateur et le serveur WebSocket. La transmission directe ultérieure des données entre les deux élimine le besoin d'établir une connexion et de répondre.

Ce qui suit est une brève description de l'API du serveur WebSocket et de l'API client.

API du serveur WebSocket

Le serveur WebSocket a été essentiellement pris en charge par divers fabricants de serveurs d'applications grand public conformes à l'API de spécification standard JEE JSR356 (voir la spécification API JSR356 WebSocket pour plus de détails), dont certains sont répertoriés ci-dessous. Les serveurs d'applications commerciaux et open source courants prennent en charge le serveur WebSocket :

Tableau 1. Prise en charge du serveur WebSocket

Fabricant Remarques

IBM WebSphere WebSphere 8.0 ou supérieur est pris en charge, et les versions antérieures à 7.X combinées avec MQTT prennent en charge des connexions HTTP longues similaires.

Oracle WebLogic WebLogic 12c est pris en charge, les versions 11g et 10g prennent en charge des connexions similaires. Connexions HTTP longues via HTTP Publish

Prise en charge de Microsoft IIS IIS 7.0

Prise en charge d'Apache Tomcat Tomcat 7.0.5+, 7.0.2X et 7.0.3X via une API personnalisée

                                Jetty 7.0+ prend en charge l'API socket.*, vous pouvez utiliser l'annotation @ServerEndpoint comme objet Java ordinaire (POJO) comme point de terminaison du serveur WebSocket. L'exemple de code est le suivant :

Listing 3. API du serveur WebSocket. exemple

Explication du code :

Le code concis ci-dessus établit un serveur WebSocket Le point de terminaison d'annotation de @ServerEndpoint("/echo") indique que le serveur WebSocket est exécuté sur ws. ://[IP du serveur ou nom de domaine]:[Port du serveur]/websockets/echo access endpoint, le navigateur client peut déjà initier de longues connexions HTTP à l'API client WebSocket.

Les classes annotées avec ServerEndpoint doivent avoir un constructeur public sans paramètre. La méthode Java annotée avec @onMessage est utilisée pour recevoir les informations WebSocket entrantes. Ces informations peuvent être au format texte ou au format binaire.
@ServerEndpoint("/echo")
 public class EchoEndpoint {
 @OnOpen
 public void onOpen(Session session) throws IOException {
 //以下代码省略...
 }
 
 @OnMessage
 public String onMessage(String message) {
 //以下代码省略...
 }
 @Message(maxMessageSize=6)
 public void receiveMessage(String s) {
 //以下代码省略...
 } 
 @OnError
 public void onError(Throwable t) {
 //以下代码省略...
 }
 
 @OnClose
 public void onClose(Session session, CloseReason reason) {
 //以下代码省略...
 } 
 
 }

OnOpen 在这个端点一个新的连接建立时被调用。参数提供了连接的另一端的更多细节。Session 表明两个 WebSocket 端点对话连接的另一端,可以理解为类似 HTTPSession 的概念。

OnClose 在连接被终止时调用。参数 closeReason 可封装更多细节,如为什么一个 WebSocket 连接关闭。

更高级的定制如 @Message 注释,MaxMessageSize 属性可以被用来定义消息字节最大限制,在示例程序中,如果超过 6 个字节的信息被接收,就报告错误和连接关闭。

注意:早期不同应用服务器支持的 WebSocket 方式不尽相同,即使同一厂商,不同版本也有细微差别,如 Tomcat 服务器 7.0.5 以上的版本都是标准 JSR356 规范实现,而 7.0.2x/7.0.3X 的版本使用自定义 API (WebSocketServlet 和 StreamInbound, 前者是一个容器,用来初始化 WebSocket 环境;后者是用来具体处理 WebSocket 请求和响应,详见案例分析部分),且 Tomcat7.0.3x 与 7.0.2x 的 createWebSocketInbound 方法的定义不同,增加了一个 HttpServletRequest 参数,使得可以从 request 参数中获取更多 WebSocket 客户端的信息,如下代码所示:

清单 4.Tomcat7.0.3X 版本 WebSocket API

public class EchoServlet extends WebSocketServlet {
@Override
protected StreamInbound createWebSocketInbound(String subProtocol,
HttpServletRequest request) {
 //以下代码省略....
return new MessageInbound() {
 //以下代码省略....
}
protected void onBinaryMessage(ByteBuffer buffer)
throws IOException {
 //以下代码省略...
}
protected void onTextMessage(CharBuffer buffer) throws IOException {
 getWsOutbound().writeTextMessage(buffer);
 //以下代码省略...
}
};
}
}

因此选择 WebSocket 的 Server 端重点需要选择其版本,通常情况下,更新的版本对 WebSocket 的支持是标准 JSR 规范 API,但也要考虑开发易用性及老版本程序移植性等方面的问题,如下文所述的客户案例,就是因为客户要求统一应用服务器版本所以使用的 Tomcat 7.0.3X 版本的 WebSocketServlet 实现,而不是 JSR356 的 @ServerEndpoint 注释端点。

WebSocket 客户端 API

对于 WebSocket 客户端,主流的浏览器(包括 PC 和移动终端)现已都支持标准的 HTML5 的 WebSocket API,这意味着客户端的 WebSocket JavaScirpt 脚本具备良好的一致性和跨平台特性,以下列举了常见的浏览器厂商对 WebSocket 的支持情况:

表 2.WebSocket 客户端支持

浏览器             支持情况

Chrome    Chrome version 4+支持    

Firefox    Firefox version 5+支持    

IE    IE version 10+支持    

Safari    IOS 5+支持    

Android Brower    Android 4.5+支持    

客户端 WebSocket API 基本上已经在各个主流浏览器厂商中实现了统一,因此使用标准 HTML5 定义的 WebSocket 客户端的 JavaScript API 即可,当然也可以使用业界满足 WebSocket 标准规范的开源框架,如 Socket.io。

以下以一段代码示例说明 WebSocket 的客户端实现:

清单 5.WebSocket 客户端 API 示例

 var ws = new WebSocket(“ws://echo.websocket.org”); 
 ws.onopen = function(){ws.send(“Test!”); }; 
 ws.onmessage = function(evt){console.log(evt.data);ws.close();}; 
 ws.onclose = function(evt){console.log(“WebSocketClosed!”);}; 
 ws.onerror = function(evt){console.log(“WebSocketError!”);};

第一行代码是在申请一个 WebSocket 对象,参数是需要连接的服务器端的地址,同 HTTP 协议开头一样,WebSocket 协议的 URL 使用 ws://开头,另外安全的 WebSocket 协议使用 wss://开头。

第二行到第五行为 WebSocket 对象注册消息的处理函数,WebSocket 对象一共支持四个消息 onopen, onmessage, onclose 和 onerror,有了这 4 个事件,我们就可以很容易很轻松的驾驭 WebSocket。

Lorsque le navigateur et le WebSocketServer sont connectés avec succès, le message onopen sera déclenché ; si la connexion échoue, l'envoi et la réception des données échouent, ou s'il y a une erreur dans le traitement des données, le navigateur déclenchera le message d'erreur lorsque le navigateur ; reçoit les données envoyées par le WebSocketServer, il déclenchera le message onmessage, le paramètre evt contient les données transmises par le Serveur ; lorsque le Navigateur recevra la demande de fermeture de connexion envoyée par le WebSocketServer, le message onclose sera déclenché. Nous pouvons voir que toutes les opérations sont déclenchées à l'aide de rappels asynchrones, ce qui ne bloquera pas l'interface utilisateur, permettra d'obtenir un temps de réponse plus rapide et offrira une meilleure expérience utilisateur.


Déclaration:
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