web-dev-qa-db-fra.com

nodejs: Ajax vs Socket.IO, avantages et inconvénients

J'ai pensé à me débarrasser de tous les appels Ajax côté client (jQuery) et à la place utiliser une connexion socket permanente (Socket.IO).

Par conséquent, j'utiliserais des écouteurs/émetteurs d'événements côté client et côté serveur.

Ex. un événement de clic est déclenché par l'utilisateur dans le navigateur, l'émetteur côté client pousse l'événement via une connexion socket au serveur. L'écouteur côté serveur réagit à l'événement entrant et repousse l'événement "terminé" au client. L'écouteur du client réagit à l'événement entrant en s'effaçant dans l'élément DIV.

Est-ce que cela a du sens? Avantages et inconvénients?

45
ezmilhouse

L'envoi de messages à sens unique et l'invocation de rappels peuvent devenir très compliqués.

$.get('/api', sendData, returnFunction); est plus propre que socket.emit('sendApi', sendData);socket.on('receiveApi', returnFunction);

C'est pourquoi dnode et nowjs ont été construits sur socket.io pour rendre les choses gérables. Toujours piloté par les événements mais sans renoncer aux rappels.

6
generalhenry

Il y a beaucoup de désinformation courante dans ce fil qui est très inexacte.

TL/DR; WebSocket remplace HTTP pour les applications! Il a été conçu par Google avec l'aide de Microsoft et de nombreuses autres grandes sociétés. Tous les navigateurs le prennent en charge. Il n'y a aucun inconvénient.

SocketIO est construit au-dessus du protocole WebSocket ( RFC 6455 ). Il a été conçu pour remplacer entièrement AJAX. Il n'a aucun problème d'évolutivité. Il fonctionne plus rapidement que AJAX tout en consommant un ordre de grandeur moins de ressources.

AJAX a 10 ans et est construit au-dessus d'une seule fonction JavaScript XMLHTTPRequest qui a été ajoutée pour permettre les rappels aux serveurs sans recharger la page entière.

En d'autres termes, AJAX est un protocole de document (HTTP) avec une seule fonction JavaScript.

En revanche, WebSocket est un protocole d'application conçu pour remplacer entièrement HTTP. Lorsque vous mettez à niveau une connexion HTTP (en demandant le protocole WebSocket), vous activez la communication bidirectionnelle en duplex intégral avec le serveur et aucune négociation de protocole n'est impliquée quoi qu'il en soit. Avec AJAX, vous devez soit activer keep-alive (qui est le même que SocketIO, uniquement le protocole plus ancien), soit forcer de nouvelles poignées de main HTTP, qui bloquent le serveur, chaque fois que vous faites une demande AJAX.

Un serveur SocketIO exécuté au-dessus de Node peut gérer 100 000 connexions simultanées en mode de maintien en utilisant seulement 4 Go de RAM et un seul processeur, et cette limite est causée par le moteur de collecte des ordures V8, pas le protocole. Vous n'y arriverez jamais, jamais avec AJAX, même dans vos rêves les plus fous.

Pourquoi SocketIO est tellement plus rapide et consomme tellement moins de ressources

Encore une fois, la raison principale en est que WebSocket a été conçu pour les applications, et AJAX est une solution de contournement pour activer les applications par-dessus un protocole de document.

Si vous plongez dans le protocole HTTP et utilisez des frameworks MVC, vous verrez qu'une seule demande AJAX transmettra en fait 700 à 900 octets de charge de protocole uniquement à AJAX vers une URL (sans aucun de vos propre charge utile). En contraste frappant, WebSocket utilise environ 10 octets, soit environ 70 fois moins de données pour parler avec le serveur.

Étant donné que SocketIO maintient une connexion ouverte, il n'y a pas de prise de contact et le temps de réponse du serveur est limité au temps d'aller-retour ou de ping vers le serveur lui-même.

Il y a des informations erronées selon lesquelles une connexion socket est une connexion port ; ce n'est pas. Une connexion socket n'est qu'une entrée dans un tableau. Très peu de ressources sont consommées et un seul serveur peut fournir 1 000 000+ connexions WebSocket. Un serveur AWS XXL peut et héberge 1 000 000+ connexions SocketIO.

Une connexion AJAX gzip/dégonfle tous les en-têtes HTTP, décode les en-têtes, encode les en-têtes et fait tourner un thread de serveur HTTP pour traiter la demande, encore une fois, car il s'agit d'un protocole de document; le serveur a été conçu pour cracher des documents une seule fois.

En revanche, WebSocket stocke simplement une entrée dans une table pour une connexion, environ 40 à 80 octets. C'est littéralement ça. Aucun sondage n'a lieu du tout.

WebSocket a été conçu à l'échelle.

En ce qui concerne SocketIO étant désordonné ... Ce n'est pas du tout le cas. AJAX est en désordre, vous avez besoin d'une promesse/réponse.

Avec SocketIO, vous avez simplement des émetteurs et des récepteurs; ils n'ont même pas besoin de se connaître; aucun système de promesse n'est nécessaire:

Pour demander une liste d'utilisateurs, il vous suffit d'envoyer un message au serveur ...

socket.emit("giveMeTheUsers");

Lorsque le serveur est prêt, il vous renverra un autre message. Tada, vous avez terminé. Donc, pour traiter une liste d'utilisateurs, vous dites simplement quoi faire lorsque vous obtenez une réponse que vous recherchez ...

socket.on("HereAreTheUsers", showUsers(data) );

C'est ça. Où est le bordel? Eh bien, il n'y en a pas :) Séparation des préoccupations? Fini pour toi. Verrouiller le client pour qu'il sache qu'il doit attendre? Ils n'ont pas à attendre :) Vous pouvez obtenir une nouvelle liste d'utilisateurs à chaque fois ... Le serveur peut même lire n'importe quelle commande d'interface utilisateur de cette façon ... Les clients peuvent se connecter à les uns les autres sans même utiliser de serveur avec WebRTC ...

Système de chat dans SocketIO? 10 lignes de code . Vidéoconférence en temps réel? 80 lignes de code Oui ... Luke ... Rejoignez-moi. utilisez le bon protocole pour le travail ... Si vous écrivez une application ... utilisez un protocole d'application.

Je pense que le problème et la confusion viennent ici de personnes habituées à utiliser AJAX et réflexion ils ont besoin de tout le protocole de promesse supplémentaire sur le client et d'une API REST à l'arrière ... Eh bien, vous ne le faites pas. :) Ce n'est plus nécessaire :)

oui, vous avez bien lu ... une REST API n'est plus nécessaire lorsque vous décidez de passer à WebSocket. REST est en fait obsolète. si vous écrivez une application de bureau, communiquez-vous avec la boîte de dialogue avec REST? Non :) C'est assez stupide.

SocketIO, l'utilisation de WebSocket fait la même chose pour vous ... vous pouvez commencer à penser du côté client aussi simple que la boîte de dialogue de votre application. Vous n'avez plus du tout besoin de REST.

En fait, si vous essayez d'utiliser REST en utilisant WebSocket, c'est tout aussi stupide que d'utiliser REST comme protocole de communication pour une boîte de dialogue de bureau ... cela n'a absolument aucun intérêt.

Qu'est-ce que tu dis Timmy? Qu'en est-il des autres applications qui souhaitent utiliser votre application? Vous devriez leur donner accès à REST? Timmy ... WebSocket est sorti depuis 4 ans ... Demandez-leur simplement de se connecter à votre application en utilisant WebSocket, et laissez-les demander les messages en utilisant ce protocole ... consommer 50 fois moins de ressources, être beaucoup plus rapide et 10 fois plus facile à développer ... Pourquoi soutenir le passé quand on crée le futur?

Bien sûr, il existe des cas d'utilisation pour REST, mais ils concernent tous des systèmes plus anciens et obsolètes ... La plupart des gens ne le savent pas encore.

MISE À JOUR:

Un [~ # ~] beaucoup [~ # ~] de personnes m'ont demandé récemment comment commencer à écrire une application en 2018 (et maintenant bientôt 2019) en utilisant WebSockets, que la barrière semble vraiment élevé, qu'une fois qu'ils jouent avec Socket.IO, ils ne savent pas où se tourner ni quoi apprendre.

Heureusement, les 3 dernières années ont été très gentilles avec WebSockets ...

Il existe maintenant 3 cadres principaux qui prennent en charge [~ # ~] à la fois [~ # ~] REST et WebSocket, et même des protocoles IoT ou d'autres protocoles minimaux/rapides comme ZeroMQ, et vous n'avez à vous soucier de rien de tout cela; vous obtenez juste un support pour cela hors de la boîte.

Note: Bien que Meteor soit de loin le plus populaire, je le laisse de côté car bien qu'il s'agisse d'un framework WebSocket très, très bien financé, toute personne qui a codé avec Meteor pendant quelques années le fera vous dire, c'est un gâchis interne et un cauchemar à l'échelle. Un peu comme WordPress est pour PHP, il est là, il est populaire, mais ce n'est pas très bien fait. Ce n'est pas bien pensé et ça va bientôt mourir. Désolé les gens de Meteor, mais découvrez ces 3 autres projets par rapport à Meteor, et vous jetterez Meteor le même jour :)

Avec tous les frameworks ci-dessous, vous écrivez votre service une fois et vous obtenez à la fois REST et le support WebSocket. De plus, c'est une seule ligne de code de configuration pour permuter entre presque n'importe quelle base de données backend.

Feathers Plus facile à utiliser, fonctionne de la même façon sur le devant et le backend, et prend en charge la plupart des fonctionnalités, Feathers est une collection d'emballages légers pour les outils existants comme express. En utilisant des outils impressionnants comme feathers-vuex, vous pouvez créer des services immuables qui sont entièrement moquables, prendre en charge REST, WebSocket et d'autres protocoles (en utilisant Primus), et obtenir des opérations CRUD complètes gratuites, y compris la recherche et la pagination, sans une seule ligne de code (juste quelques config). Fonctionne également très bien avec des données générées telles que json-schema-faker afin que vous puissiez non seulement vous moquer complètement des choses, vous pouvez vous en moquer avec des données aléatoires mais valides. Vous pouvez câbler une application pour prendre en charge la recherche de saisie anticipée, créer, supprimer et modifier, avec pas de code (juste config). Comme certains d'entre vous le savent peut-être, une configuration de code à travers appropriée est le plus grand obstacle à l'auto-modification du code. Feathers le fait bien et vous poussera vers l'avant du pack dans le futur de la conception d'applications.

Moleculer Moleculer est malheureusement un ordre de grandeur meilleur au niveau du backend que Feathers. Alors que les plumes fonctionneront et vous laisseront évoluer à l'infini, les plumes ne commencent tout simplement pas à penser à des choses comme le clustering de production, les consoles de serveurs en direct, la tolérance aux pannes, les journaux de tuyauterie prêts à l'emploi ou les passerelles API (alors que j'ai construit une passerelle d'API de production à partir de Feathers, Moleculer le fait bien, bien mieux). Moleculer est également la croissance la plus rapide, à la fois en popularité et en nouvelles fonctionnalités, que n'importe quel framework WebSocket.

Le coup gagnant avec Moleculer est que vous pouvez utiliser un frontal Feathers ou ActionHero avec un backend Moleculer, et bien que vous perdiez certains générateurs, vous gagnez beaucoup de qualité de production.

Pour cette raison, je recommande d'apprendre Feathers sur le front et le backend, et une fois que vous avez créé votre première application, essayez de basculer votre backend sur Moleculer. Moleculer est plus difficile à démarrer, mais uniquement parce qu'il résout tous les problèmes de mise à l'échelle pour vous, et ces informations peuvent dérouter les nouveaux utilisateurs.

ActionHero Répertorié ici comme une alternative viable, mais Feathers et Moleculer sont de meilleures implémentations. Si quelque chose sur ActionHero ne vous accompagne pas, ne l'utilisez pas; il y a deux meilleures façons ci-dessus qui vous donnent plus, plus rapidement.

REMARQUE: Les passerelles API sont l'avenir, et les 3 ci-dessus les prennent en charge, mais Moleculer vous le donne littéralement prêt à l'emploi. Une passerelle API vous permet de masser votre interaction client, permettant la mise en cache, la mémorisation, la messagerie client à client, la liste noire, l'enregistrement, la tolérance aux pannes et tous les autres problèmes de mise à l'échelle à gérer par un composant de plate-forme unique. Le couplage de votre passerelle API avec Kubernetes vous permettra d'évoluer à l'infini avec le moins de problèmes possible. C'est la meilleure méthode de conception disponible pour les applications évolutives.

56
Nick Steele

Socket.IO utilise une connexion persistante entre le client et le serveur, vous atteindrez donc une limite maximale de connexions simultanées en fonction des ressources dont vous disposez côté serveur, tandis que davantage de demandes asynchrones Ajax peuvent être traitées avec les mêmes ressources.

Socket.IO est principalement conçu pour les connexions en temps réel et bidirectionnelles entre le client et le serveur et dans certaines applications, il n'est pas nécessaire de maintenir des connexions permanentes. D'un autre côté, les connexions asynchrones Ajax doivent passer la phase de configuration de la connexion HTTP et envoyer les données d'en-tête et tous les cookies à chaque demande.

Socket.IO a été conçu comme un serveur à processus unique et peut présenter des problèmes d'évolutivité en fonction des ressources du serveur auxquelles vous êtes lié.

Socket.IO n'est pas bien adapté aux applications lorsque vous préférez mettre en cache les résultats des demandes des clients.

Les applications Socket.IO rencontrent des difficultés avec l'optimisation SEO et l'indexation des moteurs de recherche.

Socket.IO n'est pas un standard et n'est pas équivalent à l'API W3C Web Socket, il utilise l'API Web Socket actuelle si le navigateur le prend en charge, socket.io créé par une personne pour résoudre la compatibilité entre navigateurs dans les applications en temps réel et est si jeune, environ 1 an vieux. Sa courbe d'apprentissage, moins de développeurs et de ressources communautaires par rapport à ajax/jquery, la maintenance à long terme et moins de besoins ou de meilleures options à l'avenir peuvent être importants pour les équipes de développeurs pour faire leur code basé sur socket.io ou non.

21
Reza Hashemi