Protocole WebSockets vs HTTP

330

Il existe de nombreux blogs et discussions sur websocket et HTTP, et de nombreux développeurs et sites préconisent fortement les websockets, mais je ne comprends toujours pas pourquoi.

par exemple (arguments des amoureux du websocket):

HTML5 Web Sockets représente la prochaine évolution des communications Web: un canal de communication bidirectionnel en duplex intégral qui fonctionne via un seul socket sur le Web. ( http://www.websocket.org/quantum.html )

HTTP prend en charge la diffusion en continu: demandez la diffusion en continu du corps (vous l'utilisez lors du téléchargement de fichiers volumineux) et la réponse en continu.

Lors de l'établissement de la connexion avec WebSocket, le client et le serveur échangent des données par trame de 2 octets chacune, contre 8 kilo-octets d'en-tête http lorsque vous effectuez une interrogation continue.

Pourquoi ces 2 octets n'incluent-ils pas la surcharge TCP et sous les protocoles TCP?

GET /about.html HTTP/1.1
Host: example.org

Il s'agit d'un en-tête http ~ 48 octets.

Encodage HTTP en morceaux - https://en.wikipedia.org/wiki/Chunked_transfer_encoding :

23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0
  • Ainsi, les frais généraux par morceau ne sont pas importants.

De plus, les deux protocoles fonctionnent sur TCP, donc tous les problèmes TCP avec les connexions longue durée sont toujours là.

Des questions:

  1. Pourquoi le protocole websockets est-il meilleur?
  2. Pourquoi a-t-il été implémenté au lieu de mettre à jour le protocole http?
4esn0k
la source
2
Quelle est ta question?
Jonas
@Jonas, 1) pourquoi le protocole websockets est-il meilleur? 2) Pourquoi a-t-il été implémenté au lieu de mettre à jour le protocole http? 3) Pourquoi les websockets sont-ils si promus?
4esn0k
@JoachimPileborg, vous pouvez le faire avec des sockets TCP ou http aussi pour les applications de bureau; et vous devez utiliser WebRTC pour établir une communication de navigateur à navigateur pour le site Web
4esn0k
@JoachimPileborg, c'est webRTC pour navigateur à navigateur, pas websockets
4esn0k
@ 4esn0k, WS n'est pas mieux, ils sont différents et meilleurs pour certaines tâches spécifiques. 3) C'est une nouvelle fonctionnalité que les gens devraient connaître et ouvrir de nouvelles possibilités pour le Web
Jonas

Réponses:

491

1) Pourquoi le protocole WebSockets est-il meilleur?

WebSockets est préférable pour les situations impliquant une communication à faible latence, en particulier pour les messages à client à faible latence. Pour les données du serveur au client, vous pouvez obtenir une latence assez faible en utilisant des connexions de longue date et un transfert en bloc. Cependant, cela n'aide pas avec la latence client-serveur qui nécessite une nouvelle connexion pour chaque message client-serveur.

Votre prise de contact HTTP de 48 octets n'est pas réaliste pour les connexions de navigateur HTTP réelles où il y a souvent plusieurs kilo-octets de données envoyées dans le cadre de la demande (dans les deux sens), y compris de nombreux en-têtes et données de cookies. Voici un exemple de demande / réponse à l'utilisation de Chrome:

Exemple de demande (2800 octets, y compris les données des cookies, 490 octets sans les données des cookies):

GET / HTTP/1.1
Host: www.cnn.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.68 Safari/537.17
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: [[[2428 byte of cookie data]]]

Exemple de réponse (355 octets):

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 13 Feb 2013 18:56:27 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: CG=US:TX:Arlington; path=/
Last-Modified: Wed, 13 Feb 2013 18:55:22 GMT
Vary: Accept-Encoding
Cache-Control: max-age=60, private
Expires: Wed, 13 Feb 2013 18:56:54 GMT
Content-Encoding: gzip

HTTP et WebSockets ont des prises de contact de connexion initiale de taille équivalente, mais avec une connexion WebSocket, la prise de contact initiale est effectuée une fois, puis les petits messages n'ont que 6 octets de surcharge (2 pour l'en-tête et 4 pour la valeur de masque). La surcharge de latence ne vient pas tant de la taille des en-têtes, mais de la logique pour analyser / gérer / stocker ces en-têtes. De plus, la latence de configuration de la connexion TCP est probablement un facteur plus important que la taille ou le temps de traitement pour chaque demande.

2) Pourquoi a-t-il été implémenté au lieu de mettre à jour le protocole HTTP?

Des efforts sont en cours pour réorganiser le protocole HTTP pour obtenir de meilleures performances et une latence plus faible, tels que SPDY , HTTP 2.0 et QUIC . Cela améliorera la situation pour les requêtes HTTP normales, mais il est probable que WebSockets et / ou WebRTC DataChannel auront toujours une latence plus faible pour le transfert de données client à serveur que le protocole HTTP (ou il sera utilisé dans un mode qui ressemble beaucoup à WebSockets de toute façon).

Mettre à jour :

Voici un cadre pour réfléchir aux protocoles Web:

  • TCP : couche de transport de bas niveau, bidirectionnelle, duplex intégral et garantie de commande. Pas de support de navigateur (sauf via plugin / Flash).
  • HTTP 1.0 : protocole de transport requête-réponse en couches sur TCP. Le client fait une demande complète, le serveur donne une réponse complète, puis la connexion est fermée. Les méthodes de requête (GET, POST, HEAD) ont une signification transactionnelle spécifique pour les ressources sur le serveur.
  • HTTP 1.1 : conserve la nature demande-réponse de HTTP 1.0, mais permet à la connexion de rester ouverte pour plusieurs demandes complètes / réponses complètes (une réponse par demande). Il y a toujours des en-têtes complets dans la demande et la réponse, mais la connexion est réutilisée et non fermée. HTTP 1.1 a également ajouté quelques méthodes de demande supplémentaires (OPTIONS, PUT, DELETE, TRACE, CONNECT) qui ont également des significations transactionnelles spécifiques. Cependant, comme indiqué dans l' introduction du projet de proposition HTTP 2.0, le pipelining HTTP 1.1 n'est pas largement déployé, ce qui limite considérablement l'utilité de HTTP 1.1 pour résoudre la latence entre les navigateurs et les serveurs.
  • Long-poll : sorte de "hack" à HTTP (1.0 ou 1.1) où le serveur ne répond pas immédiatement (ou ne répond que partiellement avec des en-têtes) à la demande du client. Après une réponse du serveur, le client envoie immédiatement une nouvelle demande (en utilisant la même connexion si sur HTTP 1.1).
  • Streaming HTTP : une variété de techniques (réponse en plusieurs parties / fragmentée) qui permettent au serveur d'envoyer plus d'une réponse à une seule demande client. Le W3C standardise cela en tant qu'événements envoyés par le serveur à l' aide d'un text/event-streamtype MIME. L'API du navigateur (qui est assez similaire à l'API WebSocket) est appelée l'API EventSource.
  • Poussée de comète / serveur : il s'agit d'un terme générique qui inclut à la fois le long poll et le streaming HTTP. Les bibliothèques de comètes prennent généralement en charge plusieurs techniques pour essayer de maximiser la prise en charge inter-navigateurs et inter-serveurs.
  • WebSockets : une couche de transport TCP intégrée qui utilise une poignée de main de mise à niveau conviviale HTTP. Contrairement à TCP, qui est un transport en continu, WebSockets est un transport basé sur les messages: les messages sont délimités sur le câble et sont réassemblés en totalité avant la livraison à l'application. Les connexions WebSocket sont bidirectionnelles, duplex intégral et de longue durée. Après la demande / réponse initiale de prise de contact, il n'y a pas de sémantique transactionnelle et il y a très peu de surcharge par message. Le client et le serveur peuvent envoyer des messages à tout moment et doivent gérer la réception des messages de manière asynchrone.
  • SPDY : une proposition lancée par Google pour étendre HTTP en utilisant un protocole de fil plus efficace mais en conservant toutes les sémantiques HTTP (demande / réponse, cookies, encodage). SPDY introduit un nouveau format de trame (avec des trames à longueur préfixée) et spécifie un moyen de superposer les paires requête / réponse HTTP sur la nouvelle couche de trame. Les en-têtes peuvent être compressés et de nouveaux en-têtes peuvent être envoyés une fois la connexion établie. Il existe des implémentations réelles de SPDY dans les navigateurs et les serveurs.
  • HTTP 2.0 : a des objectifs similaires à SPDY: réduire la latence et la surcharge HTTP tout en préservant la sémantique HTTP. Le brouillon actuel est dérivé de SPDY et définit une mise à niveau de prise de contact et de cadrage de données qui est très similaire à la norme WebSocket pour la prise de contact et le cadrage. Une autre proposition de brouillon HTTP 2.0 (httpbis-speed-Mobility) utilise en fait des WebSockets pour la couche de transport et ajoute le multiplexage SPDY et le mappage HTTP en tant qu'extension WebSocket (les extensions WebSocket sont négociées pendant la prise de contact).
  • WebRTC / CU-WebRTC : propositions pour permettre la connectivité d'égal à égal entre les navigateurs. Cela peut permettre une communication à latence moyenne et maximale inférieure, car le transport sous-jacent est SDP / datagramme plutôt que TCP. Cela permet une livraison dans le désordre des paquets / messages, ce qui évite le problème TCP des pics de latence causés par les paquets abandonnés qui retardent la livraison de tous les paquets suivants (pour garantir la livraison dans l'ordre).
  • QUIC : est un protocole expérimental visant à réduire la latence Web par rapport à celle de TCP. En surface, QUIC est très similaire à TCP + TLS + SPDY implémenté sur UDP. QUIC fournit un multiplexage et un contrôle de flux équivalent à HTTP / 2, une sécurité équivalente à TLS et une sémantique de connexion, une fiabilité et un contrôle de congestion équivalents à TCP. Étant donné que TCP est implémenté dans les noyaux du système d'exploitation et le micrologiciel du boîtier de médiation, apporter des modifications importantes à TCP est presque impossible. Cependant, puisque QUIC est construit sur UDP, il ne souffre pas de telles limitations. QUIC est conçu et optimisé pour la sémantique HTTP / 2.

Références :

Kanaka
la source
1
>> Cependant, cela n'aide pas avec la latence client-serveur qui nécessite une nouvelle connexion pour chaque message client-serveur. - qu'en est-il du streaming du corps de réponse? je sais, l'API XMLHttpRequest ne le permet pas, mais il existe. avec le streaming sur le serveur, vous pouvez diffuser du côté client.
4esn0k
8
@Philipp, il a de toute façon posé une question que je souhaitais rechercher et documenter de manière approfondie. La question des WebSockets par rapport aux autres mécanismes basés sur HTTP revient assez souvent, alors maintenant il y a une bonne référence à lier. Mais oui, il semble probable que le demandeur cherchait des preuves pour sauvegarder une notion préconçue sur WebSockets vs HTTP, d'autant plus qu'il n'a jamais sélectionné de réponse ni attribué de prime.
kanaka
9
Merci beaucoup pour cet aperçu très agréable et précis des protocoles.
Martin Meeser
2
@WardC caniuse.com donne des informations sur la compatibilité du navigateur (y compris mobile).
kanaka
3
@ www139, non, au niveau du protocole WebSocket, la connexion reste ouverte jusqu'à ce que l'un ou l'autre côté ferme la connexion. Vous devrez peut-être également vous soucier des délais d'expiration TCP (un problème avec tout protocole basé sur TCP), mais tout type de trafic toutes les minutes ou deux gardera la connexion ouverte. En fait, la définition du protocole WebSocket spécifie un type de trame ping / pong, bien que même sans cela, vous pourriez envoyer un seul octet (plus un en-tête de deux octets) et cela garderait la connexion ouverte. 2-3 octets toutes les deux minutes ne sont pas du tout un impact significatif sur la bande passante.
kanaka
130

Vous semblez supposer que WebSocket remplace HTTP. Ce n'est pas. C'est une extension.

Les principaux cas d'utilisation des WebSockets sont les applications Javascript qui s'exécutent dans le navigateur Web et reçoivent des données en temps réel d'un serveur. Les jeux en sont un bon exemple.

Avant WebSockets, la seule méthode permettant aux applications Javascript d'interagir avec un serveur était d'utiliser XmlHttpRequest. Mais ceux-ci ont un inconvénient majeur: le serveur ne peut pas envoyer de données à moins que le client ne l'ait explicitement demandé.

Mais la nouvelle fonctionnalité WebSocket permet au serveur d'envoyer des données quand il le souhaite. Cela permet de mettre en œuvre des jeux basés sur un navigateur avec une latence beaucoup plus faible et sans avoir à utiliser des hacks laids comme les plugins AJAX à longue interrogation ou les navigateurs.

Alors pourquoi ne pas utiliser HTTP normal avec des requêtes et des réponses en streaming

Dans un commentaire à une autre réponse, vous avez suggéré de simplement diffuser la demande client et le corps de réponse de manière asynchrone.

En fait, les WebSockets sont essentiellement cela. Une tentative d'ouverture d'une connexion WebSocket à partir du client ressemble au début à une requête HTTP, mais une directive spéciale dans l'en-tête (Upgrade: websocket) indique au serveur de commencer à communiquer dans ce mode asynchrone. Les premières versions du protocole WebSocket n'étaient pas beaucoup plus que cela et une poignée de main pour s'assurer que le serveur comprenait réellement que le client voulait communiquer de manière asynchrone. Mais ensuite, on a réalisé que les serveurs proxy seraient confus par cela, car ils sont habitués au modèle de demande / réponse habituel de HTTP. Un scénario d'attaque potentiel contre les serveurs proxy a été découvert. Pour éviter cela, il était nécessaire de faire en sorte que le trafic WebSocket ne ressemble à aucun trafic HTTP normal. C'est pourquoi les touches de masquage ont été introduites dansla version finale du protocole .

Philipp
la source
>> le serveur ne peut pas envoyer de données à moins que le client ne l'ait explicitement demandé; Le navigateur Web doit initier la connexion WebSockets ... comme pour XMLHttpRequest
4esn0k
18
@ 4esn0k Le navigateur établit une connexion Websocket. Mais une fois qu'il est établi, les deux parties peuvent envoyer des données à tout moment. Ce n'est pas le cas pour XmlHttpRequest.
Philipp
1
POURQUOI ce n'est pas possible avec HTTP?
4esn0k
4
@Philipp, les jeux sont un bon exemple où les WebSockets brillent. Cependant, ce ne sont pas les données en temps réel du serveur où vous obtenez le plus gros gain. Vous pouvez obtenir une latence serveur-> client presque aussi bonne en utilisant le streaming HTTP / les connexions de longue date. Et avec des demandes de longue date, les serveurs peuvent envoyer efficacement toutes les fois qu'ils ont des données parce que le client a déjà envoyé la demande et que le serveur "retient la demande" jusqu'à ce qu'il ait des données. La plus grande victoire pour WebSockets est avec la latence client-> serveur (et donc aller-retour). Le client pouvant envoyer quand il veut sans frais généraux de demande est la vraie clé.
kanaka
1
@Philipp, une autre remarque: il existe d'autres méthodes en plus de XMLHttpRequest et WebSockets pour JavaScript pour interagir avec le serveur, y compris des iframes cachés et des balises de script à interrogation longue. Voir la page wikipedia de la comète pour plus de détails: en.wikipedia.org/wiki/Comet_(programming)
kanaka
27

Une API REST régulière utilise le HTTP comme protocole sous-jacent pour la communication, qui suit le paradigme de demande et de réponse, ce qui signifie que la communication implique que le client demande des données ou des ressources à un serveur et que le serveur réponde à ce client. Cependant, HTTP est un protocole sans état, donc chaque cycle de demande-réponse finira par devoir répéter les informations d'en-tête et de métadonnées. Cela entraîne une latence supplémentaire en cas de cycles de demande-réponse fréquemment répétés.

http

Avec WebSockets, bien que la communication démarre toujours comme une poignée de main HTTP initiale, il s'agit de mises à niveau supplémentaires pour suivre le protocole WebSockets (c'est-à-dire si le serveur et le client sont conformes au protocole car toutes les entités ne prennent pas en charge le protocole WebSockets).

Désormais, avec WebSockets, il est possible d'établir une connexion duplex intégral et persistante entre le client et un serveur. Cela signifie que, contrairement à une demande et à une réponse, la connexion reste ouverte aussi longtemps que l'application est en cours d'exécution (c'est-à-dire qu'elle est persistante), et comme elle est en duplex intégral, une communication simultanée bidirectionnelle est possible, c'est-à-dire que le serveur est désormais capable d'initier une communication et «pousser» certaines données vers le client lorsque de nouvelles données (qui intéressent le client) deviennent disponibles.

Websockets

Le protocole WebSockets est dynamique et vous permet d'implémenter le modèle de messagerie Publish-Subscribe (ou Pub / Sub) qui est le principal concept utilisé dans les technologies en temps réel où vous pouvez obtenir de nouvelles mises à jour sous la forme d'une poussée de serveur sans le le client doit demander (actualiser la page) à plusieurs reprises. Des exemples de telles applications sont le suivi de la localisation de la voiture Uber, les notifications push, la mise à jour des cours boursiers en temps réel, le chat, les jeux multijoueurs, les outils de collaboration en ligne en direct, etc.

Vous pouvez consulter un article approfondi sur Websockets qui explique l'historique de ce protocole, comment il a vu le jour, à quoi il sert et comment vous pouvez l'implémenter vous-même.

Voici une vidéo d'une présentation que j'ai faite sur les WebSockets et en quoi ils diffèrent de l'utilisation des API REST standard : Standardisation et exploitation de l'augmentation exponentielle du streaming de données

Srushtika Neelakantam
la source
24

Pour le TL; DR, voici 2 cents et une version plus simple pour vos questions:

  1. WebSockets offre ces avantages sur HTTP:

    • Connexion avec état persistante pendant la durée de la connexion
    • Faible latence: communication en temps quasi réel entre le serveur / client en raison de l'absence de surcharge de rétablissement des connexions pour chaque demande comme HTTP l'exige.
    • Full duplex: le serveur et le client peuvent envoyer / recevoir simultanément
  2. WebSocket et le protocole HTTP ont été conçus pour résoudre différents problèmes, IE WebSocket a été conçu pour améliorer la communication bidirectionnelle tandis que HTTP a été conçu pour être sans état, distribué à l'aide d'un modèle de demande / réponse. Mis à part le partage des ports pour des raisons héritées (pare-feu / pénétration du proxy), il n'y a pas beaucoup de terrain d'entente pour les combiner en un seul protocole.

Devy
la source
3
Important que vous ayez mentionné le terme avec état et apatride dans votre comparaison (Y)
Utsav T
15

Pourquoi le protocole websockets est-il meilleur?

Je ne pense pas que nous puissions les comparer côte à côte comme qui est le meilleur. Ce ne sera pas une comparaison équitable simplement parce qu'ils résolvent deux problèmes différents . Leurs exigences sont différentes. Ce sera comme comparer des pommes à des oranges. Ils sont différents.

HTTP est un protocole de requête-réponse. Le client (navigateur) veut quelque chose, le serveur le donne. C'est. Si le client de données souhaite être volumineux, le serveur peut envoyer des données en streaming pour annuler les problèmes de tampon indésirables. Ici, l'exigence ou le problème principal est de savoir comment faire la demande des clients et comment répondre aux ressources (hybertext) qu'ils demandent. C'est là que HTTP brille.

En HTTP, seule la demande du client. Le serveur ne répond que.

WebSocket n'est pas un protocole de demande-réponse où seul le client peut demander. Il s'agit d'un socket (très similaire au socket TCP). Une fois que la connexion est ouverte, chaque côté peut envoyer des données jusqu'à ce que la connexion TCP soulignée soit fermée. C'est comme une prise normale. La seule différence avec le socket TCP est que websocket peut être utilisé dans le web. Dans le Web, nous avons beaucoup de restrictions pour une socket normale. La plupart des pare-feu bloquent les autres ports que 80 et 433 utilisés par HTTP. Les proxys et intermédiaires seront également problématiques. Pour rendre le protocole plus facile à déployer sur les infrastructures Websocket existantes, utilisez la négociation HTTP pour la mise à niveau. Cela signifie que lors de la première connexion, le client a envoyé une requête HTTP pour dire au serveur "Ce n'est pas une requête HTTP, veuillez mettre à niveau vers le protocole websocket".

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Une fois que le serveur a compris la demande et mis à niveau vers le protocole websocket, aucun des protocoles HTTP ne s'est appliqué.

Ma réponse est donc: ni l'un ni l'autre n'est meilleur l'un que l'autre. Ils sont complètement différents.

Pourquoi a-t-il été implémenté au lieu de mettre à jour le protocole http?

Eh bien, nous pouvons aussi tout faire sous le nom de HTTP . Mais le ferons-nous? S'il s'agit de deux choses différentes, je préférerai deux noms différents. Hickson et Michael Carter aussi .

FranXho
la source
6

Les autres réponses ne semblent pas toucher à un aspect clé ici, c'est-à-dire que vous ne mentionnez pas la nécessité de prendre en charge un navigateur Web en tant que client. La plupart des limitations de HTTP simple ci-dessus supposent que vous travailleriez avec des implémentations de navigateur / JS.

Le protocole HTTP est entièrement capable de communiquer en duplex intégral; il est légal qu'un client effectue un POST avec un transfert de codage en blocs et qu'un serveur renvoie une réponse avec un corps de codage en blocs. Cela supprimerait la surcharge de l'en-tête juste au moment de l'initialisation.

Donc, si tout ce que vous recherchez est en duplex intégral, contrôlez à la fois le client et le serveur et que vous n'êtes pas intéressé par le cadre / les fonctionnalités supplémentaires des websockets, je dirais que HTTP est une approche plus simple avec une latence / CPU plus faible (bien que la latence ne différerait vraiment qu'en microsecondes ou moins pour les deux).

parité3
la source