web-dev-qa-db-fra.com

Ma compréhension du polling HTTP, du polling long, du streaming HTTP et des WebSockets

J'ai lu de nombreux articles sur SO et le Web concernant les mots-clés dans le titre de ma question et j'ai beaucoup appris d'eux. Certaines des questions que j'ai lues sont liées à des défis d'implémentation spécifiques tandis que d'autres se concentrent sur les généralités Je veux simplement m'assurer que j'ai compris tous les concepts et le raisonnement pour lequel la technologie X a été inventée par rapport à la technologie Y et ainsi de suite.

interrogation Http: Fondamentalement AJAX, en utilisant XmlHttpRequest.

Http Long Polling: AJAX mais le serveur conserve la réponse à moins que le serveur n'ait une mise à jour, dès qu'il a une mise à jour, il l'envoie puis le client peut envoyer une autre demande. L'inconvénient est que les données d'en-tête supplémentaires doivent être envoyées dans les deux sens, ce qui entraîne des frais supplémentaires.

Http Streaming: Similaire à une longue interrogation mais le serveur répond avec un en-tête avec "Transfer Encoding: chunked" et donc nous n'avons pas besoin d'initier une nouvelle demande chaque fois que le serveur envoie des données (et donc de sauvegarder l'en-tête supplémentaire). L'inconvénient ici est que nous devons "comprendre" et comprendre la structure des données pour faire la distinction entre plusieurs morceaux envoyés par le serveur.

Java Applet, Flash, Silverlight: Ils offrent la possibilité de se connecter à des serveurs de socket via tcp/ip mais comme ce sont des plugins, les développeurs ne veulent pas dépendre d'eux.

WebSockets: ce sont la nouvelle API qui essaie de remédier aux lacunes des méthodes ci-dessus de la manière suivante:

  • Le seul avantage des WebSockets sur les plugins comme Java Applets, Flash ou Silverlight) est que les WebSockets sont nativement intégrés aux navigateurs et ne dépendent pas des plugins.
  • Le seul avantage de WebSockets sur le streaming http est que vous n'avez pas à faire d'effort pour "comprendre" et analyser les données reçues.
  • Le seul avantage de WebSockets par rapport à l'interrogation longue est celui de l'élimination de la taille des en-têtes supplémentaires et de l'ouverture et de la fermeture de la connexion de socket à la demande.

Y a-t-il d'autres différences importantes qui me manquent? Je suis désolé si je pose à nouveau ou combine plusieurs des questions déjà sur SO en une seule question, mais je veux juste donner un sens parfait à toutes les informations qui sont là-bas sur SO et le Web concernant ces concepts.

Merci!

107
Software Guy

Il y a plus de différences que celles que vous avez identifiées.

Duplex/directionnel:

  • Unidirectionnel: sondage HTTP, sondage long, streaming.
  • Bi-direcitonal: WebSockets, mise en réseau de plugins

Par ordre de latence croissante (approximative):

  • WebSockets
  • Mise en réseau des plugins
  • Streaming HTTP
  • Interrogation longue HTTP
  • Interrogation HTTP

CORS (prise en charge multi-origine):

  • WebSockets: oui
  • Mise en réseau des plugins: Flash via une demande de stratégie (pas sûr des autres)
  • HTTP * (un support récent)

Données binaires natives (tableaux typés, blobs):

  • WebSockets: oui
  • Mise en réseau de plug-ins: pas avec Flash (nécessite le codage d'URL sur ExternalInterface)
  • HTTP *: proposition récente pour activer le support de type binaire

Bande passante pour une efficacité décroissante:

  • Mise en réseau des plugins: les sockets Flash sont brutes, sauf pour la demande de stratégie initiale
  • WebSockets: prise de contact pour la configuration de la connexion et quelques octets par trame
  • Streaming HTTP (réutilisation de la connexion au serveur)
  • HTTP long-poll: connexion pour chaque message
  • Sondage HTTP: connexion pour chaque message + aucun message de données

Prise en charge des appareils mobiles:

  • WebSocket: iOS 4.2 et supérieur. Certains Android via l'émulation Flash ou en utilisant Firefox pour Android ou Google Chrome pour Android qui fournissent tous deux prise en charge native de WebSocket.
  • Réseau de plugins: certains Android. Pas sur iOS
  • HTTP *: généralement oui

Complexité d'utilisation de Javascript (du plus simple au plus compliqué). Certes, les mesures de complexité sont quelque peu subjectives.

  • WebSockets
  • Sondage HTTP
  • Mise en réseau des plugins
  • Sondage long HTTP, streaming

Notez également qu'il existe une proposition du W3C pour normaliser le streaming HTTP appelée Server-Sent Events . Il est actuellement assez tôt dans son évolution et est conçu pour fournir une API Javascript standard avec une simplicité comparable aux WebSockets.

83
kanaka

Quelques bonnes réponses d'autres qui couvrent beaucoup de terrain. Voici un petit plus.

Le seul avantage des WebSockets sur les plugins comme Java Applets, Flash ou Silverlight) est que les WebSockets sont nativement intégrés aux navigateurs et ne dépendent pas des plugins.

Si vous entendez par là que vous pouvez utiliser Java Applets, Flash ou Silverlight pour établir une connexion socket, alors oui, c'est possible. Cependant, vous ne voyez pas cela déployé dans le monde réel trop souvent à cause des restrictions.

Par exemple, les intermédiaires peuvent et font arrêter ce trafic. La norme WebSocket a été conçue pour être compatible avec l'infrastructure HTTP existante et est donc beaucoup moins sujette à être gênée par des intermédiaires comme les pare-feu et les proxys.

De plus, WebSocket peut utiliser les ports 80 et 443 sans nécessiter de ports dédiés, toujours grâce à la conception du protocole pour être aussi compatible que possible avec l'infrastructure HTTP existante.

Ces alternatives de socket (Java, Flash et Silverlight) sont difficiles à utiliser en toute sécurité dans une architecture cross-Origin. Ainsi, les gens qui tentent souvent de les utiliser entre les origines toléreront les insécurités plutôt que de faire l'effort de le faire en toute sécurité.

Ils peuvent également nécessiter l'ouverture de ports "non standard" supplémentaires (ce que les administrateurs sont réticents à faire) ou de fichiers de stratégie qui doivent être gérés.

En bref, l'utilisation de Java, Flash ou Silverlight pour la connectivité de socket est suffisamment problématique pour que vous ne le voyiez pas trop souvent déployé dans des architectures sérieuses. Flash et Java ont cette capacité depuis probablement au moins 10 ans, et pourtant ce n'est pas répandu.

La norme WebSocket a pu commencer avec une nouvelle approche, en gardant ces restrictions à l'esprit et en espérant en avoir tiré quelques leçons.

Certaines implémentations WebSocket utilisent Flash (ou éventuellement Silverlight et/ou Java) comme solution de rechange lorsque la connectivité WebSocket ne peut pas être établie (par exemple lors de l'exécution dans un ancien navigateur ou lorsqu'un intermédiaire interfère).

Bien qu'une sorte de stratégie de secours pour ces situations soit intelligente, voire nécessaire, la plupart de ceux qui utilisent Flash et al souffriront des inconvénients décrits ci-dessus. Il ne doit pas en être ainsi - il existe des solutions de contournement pour réaliser des connexions sécurisées multi-origines en utilisant Flash, Silverlight, etc. - mais la plupart des implémentations ne le feront pas parce que ce n'est pas facile.

Par exemple, si vous comptez sur WebSocket pour une connexion inter-origine, cela fonctionnera correctement. Mais si vous exécutez ensuite dans un ancien navigateur ou qu'un pare-feu/proxy interfère et que vous comptez sur Flash, par exemple, comme solution de rechange, vous aurez du mal à faire la même connexion entre les origines. Sauf si vous ne vous souciez pas de la sécurité, bien sûr.

Cela signifie qu'il est difficile d'avoir une seule architecture unifiée qui fonctionne pour les connexions natives et non natives, à moins que vous ne soyez prêt à faire un peu de travail ou à utiliser un cadre qui l'a bien fait. Dans une architecture idéale, vous ne remarqueriez pas si les connexions étaient natives ou non; vos paramètres de sécurité fonctionneraient dans les deux cas; vos paramètres de clustering fonctionneraient toujours; votre planification de la capacité serait toujours valable; etc.

Le seul avantage de WebSockets sur le streaming http est que vous n'avez pas à faire d'effort pour "comprendre" et analyser les données reçues.

Ce n'est pas aussi simple que d'ouvrir un flux HTTP et de rester assis pendant que vos données circulent pendant des minutes, des heures ou plus. Différents clients se comportent différemment et vous devez gérer cela. Par exemple, certains clients tamponneront les données et ne les publieront pas jusqu'à ce qu'un certain seuil soit atteint. Pire encore, certains ne transmettront pas les données à l'application tant que la connexion ne sera pas fermée.

Ainsi, si vous envoyez plusieurs messages au client, il est possible que l'application cliente ne reçoive pas les données tant que 50 messages de données n'ont pas été reçus, par exemple. Ce n'est pas trop en temps réel.

Bien que le streaming HTTP puisse être une alternative viable lorsque WebSocket n'est pas disponible, ce n'est pas une panacée. Il a besoin d'une bonne compréhension pour fonctionner de manière robuste dans les badlands du Web dans des conditions réelles.

Y a-t-il d'autres différences importantes qui me manquent?

Il y a une autre chose que personne n'a encore mentionnée, alors je vais en parler.

Le protocole WebSocket a été conçu pour être une couche de transport pour les protocoles de niveau supérieur. Bien que vous puissiez envoyer des messages JSON ou autre directement via une connexion WebSocket, il peut également transporter des protocoles standard ou personnalisés.

Par exemple, vous pourriez faire AMQP ou XMPP sur WebSocket, comme les gens l'ont déjà fait. Ainsi, un client peut recevoir des messages d'un courtier AMQP comme s'il était connecté directement au courtier lui-même (et dans certains cas, c'est le cas).

Ou si vous avez un serveur existant avec un protocole personnalisé, vous pouvez le transporter sur WebSocket, étendant ainsi ce serveur principal au Web. Souvent, une application existante qui a été verrouillée dans l'entreprise peut étendre sa portée à l'aide de WebSocket, sans avoir à modifier l'infrastructure principale.

(Naturellement, vous voudriez pouvoir faire tout cela en toute sécurité, alors vérifiez auprès du fournisseur ou du fournisseur WebSocket.)

Certaines personnes ont appelé WebSocket comme TCP pour le Web. Parce que, tout comme TCP transporte des protocoles de niveau supérieur, WebSocket aussi, mais d'une manière compatible) avec une infrastructure Web.

Ainsi, bien qu'il soit toujours possible d'envoyer des messages JSON (ou autre) directement via WebSocket, il convient également de prendre en compte les protocoles existants. Parce que pour beaucoup de choses que vous voulez faire, il y a probablement un protocole qui a déjà été pensé pour le faire.

Je suis désolé si je pose à nouveau ou combine plusieurs des questions déjà sur SO en une seule question, mais je veux juste donner un sens parfait à toutes les informations qui sont là-bas sur SO et le Web concernant ces concepts.

C'était une excellente question, et les réponses ont toutes été très instructives!

13
Robin Zimmermann

Si je peux demander une chose supplémentaire: je suis tombé sur un article quelque part qui dit que le streaming http peut également être mis en cache par des mandataires alors que les websockets ne le sont pas. Qu'est-ce que ça veut dire?

(StackOverflow limite la taille des réponses aux commentaires, j'ai donc dû répondre ici plutôt qu'en ligne.)

C'est un bon point. Pour comprendre cela, pensez à un scénario HTTP traditionnel ... Imaginez qu'un navigateur ouvre une page Web, il demande donc http://example.com , disons. Le serveur répond avec HTTP qui contient le code HTML de la page. Ensuite, le navigateur voit qu'il y a des ressources dans la page, il commence donc à demander les fichiers CSS, les fichiers JavaScript et les images bien sûr. Ce sont tous des fichiers statiques qui seront les mêmes pour tous les clients qui en font la demande.

Certains mandataires mettent en cache les ressources statiques afin que les demandes ultérieures d'autres clients puissent obtenir ces ressources statiques du proxy, plutôt que d'avoir à remonter jusqu'au serveur Web central pour les obtenir. Il s'agit de la mise en cache et c'est une excellente stratégie pour décharger les demandes et le traitement de vos services centraux.

Ainsi, le client n ° 1 demande http://example.com/images/logo.gif , par exemple. Cette demande passe par le proxy jusqu'au serveur Web central, qui sert de logo.gif. Lorsque logo.gif passe par le proxy, le proxy enregistre cette image et l'associe à l'adresse http://example.com/images/logo.gif .

Lorsque le client n ° 2 arrive et demande également http://example.com/images/logo.gif , le proxy peut renvoyer l'image et aucune communication n'est requise vers le serveur Web du centre. Cela donne une réponse plus rapide à l'utilisateur final, ce qui est toujours génial, mais cela signifie également qu'il y a moins de charge sur le centre. Cela peut se traduire par des coûts matériels réduits, des coûts de mise en réseau réduits, etc. C'est donc une bonne chose.

Le problème survient lorsque le logo.gif est mis à jour sur le serveur Web. Le proxy continuera de servir l'ancienne image sans savoir qu'il y a une nouvelle image. Cela conduit à tout autour de l'expiration afin que le proxy ne cache l'image que pendant une courte période avant qu'elle "expire" et que la requête suivante passe par le proxy au serveur Web, qui actualise ensuite le cache du proxy. Il existe également des solutions plus avancées où un serveur central peut pousser vers des caches connus, etc., et les choses peuvent devenir assez sophistiquées.

Comment cela rejoint-il votre question?

Vous avez demandé à propos de la diffusion HTTP où le serveur diffuse HTTP vers un client. Mais le streaming HTTP est comme HTTP normal, sauf que vous n'arrêtez pas d'envoyer des données. Si un serveur Web sert une image, il envoie HTTP au client qui se termine finalement: vous avez envoyé l'image entière. Et si vous voulez envoyer des données, c'est exactement la même chose, mais le serveur n'envoie que très longtemps (comme c'est une image massivement gigantesque, par exemple) ou même ne se termine jamais.

Du point de vue du proxy, il ne peut pas faire la distinction entre HTTP pour une ressource statique comme une image, ou des données de streaming HTTP. Dans les deux cas, le client a fait une demande au serveur. Le mandataire se souvenait de cette demande ainsi que de la réponse. La prochaine fois que cette demande arrivera, le proxy servira la même réponse.

Donc, si votre client a fait une demande de prix des actions, par exemple, et a obtenu une réponse, le client suivant peut faire la même demande et obtenir les données mises en cache. Probablement pas ce que vous voulez! Si vous demandez des cours boursiers, vous voulez les dernières données, non?

C'est donc un problème.

Il existe des astuces et des solutions de contournement pour gérer de tels problèmes, c'est vrai. De toute évidence, vous pouvez faire fonctionner le streaming HTTP car il est utilisé aujourd'hui. Tout est transparent pour l'utilisateur final, mais les personnes qui développent et maintiennent ces architectures doivent sauter à travers des cerceaux et payer un prix. Il en résulte des architectures trop compliquées, ce qui signifie plus de maintenance, plus de matériel, plus de complexité, plus de coûts. Cela signifie également que les développeurs doivent souvent se soucier de quelque chose qu'ils ne devraient pas avoir à faire lorsqu'ils devraient se concentrer uniquement sur l'application, l'interface graphique et la logique métier - ils ne devraient pas avoir à se soucier de la communication sous-jacente.

10
Robin Zimmermann

HTTP limite le nombre de connexions qu'un client peut avoir avec un serveur à 2 (bien que cela puisse être atténué en utilisant des sous-domaines) et IE est connu pour appliquer cela avec impatience. Firefox et Chrome autorise plus (bien que je ne me souvienne pas du nombre exact de mes têtes). Cela peut ne pas sembler être un problème énorme, mais si vous utilisez constamment une connexion pour les mises à jour en temps réel, toutes les autres les demandes doivent goulot d'étranglement à travers l'autre connexion HTTP. Et il y a la question d'avoir plus de connexions ouvertes des clients met plus de charge sur le serveur.

Les WebSockets sont un protocole basé sur TCP et en tant que tels ne souffrent pas de cette limite de connexion au niveau HTTP (mais, bien sûr, la prise en charge du navigateur n'est pas uniforme).

4
TheJuice