Ma compréhension de l'interrogation HTTP, de l'interrogation longue, de la diffusion HTTP et des WebSockets

123

J'ai lu de nombreux articles sur SO et sur 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 spécifiques de mise en œuvre tandis que d'autres se concentrent sur des concepts généraux. Je veux juste m'assurer d'avoir bien compris tous les concepts et le raisonnement pour lesquels la technologie X a été inventée par rapport à la technologie Y et ainsi de suite. Alors voilà:

Interrogation Http: Fondamentalement AJAX, en utilisant XmlHttpRequest.

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

Http Streaming: Similaire à une longue interrogation, mais le serveur répond avec un en-tête avec "Transfer Encoding: chunked" et par conséquent, nous n'avons pas besoin d'initier une nouvelle demande chaque fois que le serveur envoie des données (et donc de sauvegarder la surcharge d'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 blocs envoyés par le serveur.

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

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

  • Le seul avantage des WebSockets par rapport aux plugins tels que Java Applets, Flash ou Silverlight est que les WebSockets sont nativement intégrés aux navigateurs et ne reposent pas sur des plugins.
  • Le seul avantage de WebSockets par rapport au streaming http est que vous n'avez pas à faire un effort pour «comprendre» et analyser les données reçues.
  • Le seul avantage des WebSockets par rapport à l'interrogation longue est l'élimination de la taille des en-têtes supplémentaires et l'ouverture et la fermeture de la connexion de socket pour 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 disponibles sur SO et sur le Web concernant ces concepts.

Merci!

Logiciel Guy
la source
4
Les événements envoyés par le serveur peuvent également valoir la peine d'être examinés lorsque vous n'avez pas besoin de communication bidirectionnelle.
leggetter
1
C'est une question vraiment utile. Je pense que ce serait potentiellement plus utile s'il y avait une réponse à laquelle plusieurs auteurs pourraient contribuer.
leggetter
@leggetter Merci Phil, merci pour le conseil concernant les événements envoyés par le serveur. Je souhaite en savoir plus sur les scénarios de communication bidirectionnelle. Merci.
Software Guy
1
Avec HTTP Streaming et Long-Polling, vous avez besoin d'une deuxième connexion pour une communication bidirectionnelle. Une connexion de plus longue durée pour le serveur -> communication «push» client et une seconde connexion de courte durée pour le client -> communications du serveur. Cette deuxième connexion est utilisée pour effectuer des tâches telles que la configuration et la modification des abonnements aux données. Ainsi, EventSource peut être utilisé dans une solution bidirectionnelle et est en fait une solution standardisée née du streaming HTTP et de l'interrogation longue.
leggetter
1
Vous pouvez également consulter cette classification des techniques que j'ai écrit: stackoverflow.com/questions/12078550/…
Alessandro Alinone

Réponses:

92

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
  • Réseau de plugins
  • Diffusion HTTP
  • Interrogation longue HTTP
  • Interrogation HTTP

CORS (support d'origine croisée):

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

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

  • WebSockets: oui
  • Mise en réseau des plugins: pas avec Flash (nécessite un encodage URL sur ExternalInterface)
  • HTTP *: proposition récente pour activer la prise en charge des types binaires

Bande passante en baisse d'efficacité:

  • Mise en réseau des plugins: les sockets Flash sont bruts, sauf pour la demande de politique initiale
  • WebSockets: établissement de la connexion et établissement de quelques octets par trame
  • Streaming HTTP (réutilisation de la connexion serveur)
  • HTTP long-poll: connexion pour chaque message
  • Sondage HTTP: connexion pour chaque message + pas de messages de données

Prise en charge des appareils mobiles:

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

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

  • WebSockets
  • Sondage HTTP
  • Réseau de plugins
  • Sondage HTTP long, streaming

Notez également qu'il existe une proposition du W3C pour standardiser la diffusion HTTP appelée Evénements envoyés par le serveur . Il est actuellement assez tôt dans son évolution et est conçu pour fournir une API Javascript standard avec une simplicité comparable à WebSockets.

Kanaka
la source
1
Merci beaucoup pour la gentille réponse Kanaka. Pouvez-vous me dire pourquoi / comment le streaming http a une latence plus élevée que les websockets? peut-être avec un exemple simple? Merci beaucoup.
Software Guy
2
@SoftwareGuy. De nombreuses raisons. Sur les navigateurs récents, vous pouvez utiliser le gestionnaire d'événements XMLHTTPRequest onprogress pour être averti des données. Mais la spécification dit que 50 ms est le plus petit intervalle de notification. Sinon, vous devez interroger les données de réponse. En outre, les envois client établissent une nouvelle connexion HTTP et augmentent ainsi considérablement la latence aller-retour. De plus, de nombreux serveurs Web coupent les connexions HTTP après environ 30 secondes, ce qui signifie que vous devez souvent continuer à rétablir la connexion push du serveur. J'ai vu des latences aller-retour WebSocket de 5 à 10 ms sur un réseau local. La latence du streaming HTTP serait probablement de 50 ms +.
kanaka
Merci beaucoup pour la réponse détaillée :)
Software Guy
1
@leggetter Merci Phil, vous voulez dire que l'envoi de données du client au serveur via le streaming http entraînera une surcharge? l'envoi de données au serveur est-il même possible via le streaming http sans ouvrir une nouvelle connexion? Merci.
Software Guy
1
@Nathan ressemble à un bon projet de thèse de maîtrise! Certes, l'interrogation maintiendra le système plus occupé qu'un modèle événementiel, mais quelles pourraient être exactement les économies d'énergie nécessiteraient des tests empiriques assez poussés à différentes échelles.
kanaka
13

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

Le seul avantage des WebSockets par rapport aux plugins tels que Java Applets, Flash ou Silverlight est que les WebSockets sont nativement intégrés aux navigateurs et ne reposent pas sur des plugins.

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

Par exemple, les intermédiaires peuvent arrêter ce trafic et le font. Le standard WebSocket a été conçu pour être compatible avec l'infrastructure HTTP existante et est donc beaucoup moins susceptible d'être perturbé par des intermédiaires tels que les pare-feu et les proxies.

De plus, WebSocket peut utiliser les ports 80 et 443 sans nécessiter de ports dédiés, encore une fois 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 d'origine croisée toléreront les insécurités plutôt que de s'efforcer de le faire en toute sécurité.

Ils peuvent également exiger l'ouverture de ports "non standard" supplémentaires (ce que les administrateurs répugnent à faire) ou des 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 la voyiez pas trop souvent déployée 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.

Le standard WebSocket a pu commencer avec une nouvelle approche, en gardant ces restrictions à l'esprit et, espérons-le, en ayant tiré des leçons.

Certaines implémentations WebSocket utilisent Flash (ou éventuellement Silverlight et / ou Java) comme solution de secours 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 repli 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 n'est pas nécessaire qu'il en soit ainsi - il existe des solutions de contournement pour obtenir des connexions sécurisées compatibles avec les origines croisées à l'aide de Flash, Silverlight, etc. - mais la plupart des implémentations ne le feront pas car ce n'est pas facile.

Par exemple, si vous comptez sur WebSocket pour une connexion cross-origin, cela fonctionnera correctement. Mais si vous exécutez ensuite dans un ancien navigateur ou un pare-feu / proxy interféré et comptez sur Flash, par exemple, comme solution de secours, vous aurez du mal à faire la même connexion cross-origin. À moins que vous ne vous souciez pas de la sécurité, bien sûr.

Cela signifie qu'il est difficile d'avoir une architecture unifiée unique qui fonctionne pour les connexions natives et non natives, à moins que vous ne soyez prêt à faire pas mal 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 mise en cluster fonctionneraient toujours; votre planification de la capacité tiendrait toujours; etc.

Le seul avantage de WebSockets par rapport au streaming http est que vous n'avez pas à faire un 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 mettront en mémoire tampon les données et ne les publieront pas dans l'application tant qu'un certain seuil n'est pas 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 faut une bonne compréhension pour travailler 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 quoi que ce soit directement via une connexion WebSocket, il peut également transporter des protocoles standard ou personnalisés.

Par exemple, vous pouvez 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 via WebSocket, étendant ainsi ce serveur principal au Web. Souvent, une application existante qui a été verrouillée dans l'entreprise peut élargir 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 qualifié WebSocket de TCP pour le Web. Parce que tout comme TCP transporte des protocoles de niveau supérieur, WebSocket fait de même, mais d'une manière compatible avec l'infrastructure Web.

Ainsi, bien que l'envoi de messages JSON (ou autre) directement sur WebSocket soit toujours possible, il faut également considérer 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 disponibles sur SO et sur le Web concernant ces concepts.

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

Robin Zimmermann
la source
Merci beaucoup Robin pour l'excellente aide et information. 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 proxys alors que les websockets ne le sont pas. Qu'est-ce que ça veut dire?
Software Guy
Parce que StackOverflow limite la taille des commentaires de réponse, j'ai donné ma réponse ci-dessous: stackoverflow.com/questions/12555043/…
Robin Zimmermann
@RobinZimmermann, votre réponse est ma préférée. +1 pour la très bonne réponse détaillée.
securecurve
10

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 proxys 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, donc il demande http://example.com , par exemple. Le serveur répond avec HTTP qui contient le 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 les demandent.

Certains proxys mettront 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 à retourner 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 logo.gif. Lorsque logo.gif passe par le proxy, le proxy enregistrera cette image et l'associera à 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 avec le serveur Web au centre. Cela donne une réponse plus rapide à l'utilisateur final, ce qui est toujours excellent, mais cela signifie également qu'il y a moins de charge sur le centre. Cela peut se traduire par une réduction des coûts de matériel, des coûts de réseau réduits, etc.

Le problème survient lorsque le logo.gif est mis à jour sur le serveur Web. Le proxy continuera à servir l'ancienne image sans savoir qu'il existe une nouvelle image. Cela conduit à tout un problème autour de l'expiration de sorte que le proxy ne mettra en cache l'image que pendant un court laps de temps avant qu'elle "n'expire" et que la prochaine demande passe par le proxy vers le 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, et ainsi de suite, et les choses peuvent devenir assez sophistiquées.

Comment cela se rattache-t-il à votre question?

Vous avez posé une question sur le streaming HTTP où le serveur diffuse HTTP vers un client. Mais le streaming HTTP est comme le 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 finit par se terminer: 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 si c'était une image massivement gigantesque, par exemple) ou même ne finit jamais.

Du point de vue du proxy, il ne peut pas faire la distinction entre HTTP pour une ressource statique comme une image ou les données de streaming HTTP. Dans ces deux cas, le client a fait une demande au serveur. Le mandataire s'est souvenu de cette demande ainsi que de la réponse. La prochaine fois que cette demande arrive, le proxy fournit 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 alors faire la même demande et obtenir les données mises en cache. Probablement pas ce que vous voulez! Si vous demandez les cours des actions, 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 franchir des obstacles 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 alors qu'ils devraient simplement se concentrer sur l'application, l'interface graphique et la logique métier - ils ne devraient pas avoir à se soucier de la communication sous-jacente.

Robin Zimmermann
la source
1
excellent détail Robin, merci beaucoup! j'apprécie vraiment votre réponse approfondie. J'ai déjà beaucoup appris de toutes les personnes formidables ici! :)
Software Guy
4

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 empressement. Firefox et Chrome en permettent plus (bien que je ne me souvienne pas du haut de ma tête exactement combien). Cela peut ne pas sembler être un gros problème, mais si vous utilisez une connexion en permanence pour les mises à jour en temps réel, toutes les autres demandes doivent goulot d'étranglement via l'autre connexion HTTP. Et il y a la question d'avoir plus de connexions ouvertes des clients qui met plus de charge sur le serveur.

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

Le jus
la source
merci thejuice, donc outre le problème des connexions simultanées multiples comme vous l'avez souligné, le reste de mes hypothèses concernant les websockets est-il correct?
Software Guy