web-dev-qa-db-fra.com

Les performances sont-elles la seule raison de ne pas utiliser SignalR (websockets) au lieu d'une API traditionnelle REST?

J'ai utilisé SignalR pour obtenir des fonctionnalités de messagerie en temps réel dans plusieurs de mes projets. Il semble fonctionner de manière fiable et est très facile à apprendre à utiliser.

La tentation, au moins pour moi, est d'abandonner le développement d'un service d'API Web et d'utiliser SignalR pour tout.

Je pense que cela pourrait être réalisé par une conception réfléchie, et si c'était le cas, cela signifierait beaucoup moins de code client serait nécessaire. Plus important encore, cela signifierait qu'il y aurait une seule interface vers les services plutôt qu'une interface divisée, et dans le pire des cas, on pourrait câbler cela sans penser à quand les choses sont rendues, etc.

Donc, je voudrais savoir:

  1. Y a-t-il une autre raison de ne pas utiliser SignalR au lieu de tous les services Web en plus des performances?
  2. Les performances de SignalR sont-elles suffisamment préoccupantes pour qu'il ne soit pas logique de le faire?

Cela fait longtemps que je rêve de pouvoir traduire des définitions d'objets et de services côté serveur en code d'accès aux services côté client sans quelque chose de stupide comme node.js. Par exemple, si je définis un objet intéressant InterestingObject et un service pour CRUD l'objet InterestingObjectService, je peux définir une route URL standard vers le service - disons, "/ { serviceName}/{methodName} "- mais j'ai encore besoin d'écrire du code client pour accéder au service. Puisque l'objet va être passé du client au serveur et vice-versa, il n'y a aucune raison pratique de avoir pour définir l'objet explicitement dans le code côté client, et il ne devrait pas non plus être nécessaire de définir explicitement le itinéraires pour effectuer des opérations CRUD. Je pense qu'il devrait y avoir un moyen de normaliser tout cela afin qu'il soit possible d'écrire un client en supposant que l'accès au service fonctionne du client vers le serveur et inversement de manière aussi transparente que si j'écrivais un WinForms ou = Java Applet ou Native App ou ce que vous avez.

Si SignalR est assez bon pour être utilisé à la place d'un service Web traditionnel, cela peut être un moyen viable d'y parvenir. SignalR inclut déjà des fonctionnalités pour faire fonctionner le hub comme un service que je décris, donc je pourrais définir un service de base commun (CRUD) qui offrirait toutes ces fonctionnalités hors de la boîte avec une certaine réflexion. Ensuite, je pourrais presque tenir pour acquis l'accès au service, ce qui m'évite la gêne de réécrire du code pour accéder à quelque chose qui pourrait être accessible par convention - et plus important encore, le temps que je devrais passer à écrire du code pour définir comment cela est mis à jour dans le DOM.

Après avoir lu mon montage, j'ai l'impression que cela peut être un peu absurde, alors n'hésitez pas à me demander si vous avez des questions sur ce que je veux en venir. Fondamentalement, je veux que l'accès au service soit aussi transparent que possible.

44

Ces deux technologies ont un objectif très différent.

  • REST est pour les appels ordinaires à une API, avec le client étant un acteur actif de l'échange. Lorsque le client a besoin de trouver les coordonnées GPS d'une adresse, le client lance l'appel à l'API et attend jusqu'à ce qu'il reçoive les coordonnées, ou une erreur se produit , ou un délai s’écoule.

  • Les sockets Web sont pour tout ce qui doit faire les choses dans le sens inverse. Par exemple, lorsque j'utilise un site Web intranet qui me montre en temps réel les journaux et les performances de différents serveurs, le client peut être passif et attend que le serveur lui envoie un message de journal ou une performance récemment publié métrique.

La différence est claire: dans le premier cas, le client décide quand il a besoin d'une information spécifique; dans le second cas, le client attend simplement d'être contacté et peut ne pas savoir quand il le sera.

D'une certaine manière, les deux sont interchangeables: vous pouvez implémenter des sockets web lorsque vous n'en avez pas besoin (c'est-à-dire que le client appellera le serveur via des sockets web au lieu de faire un REST) et vous pouvez utiliser l'interrogation ou l'interrogation longue comme substitut aux sockets Web (étant donné que cela a été utilisé avec succès pendant des années jusqu'à ce que les sockets Web deviennent si populaires).

Mais leur interchangeabilité a un coût:

  • Lorsque vous utilisez l'interrogation ou l'interrogation longue au lieu des sockets Web, vous perdez souvent de la bande passante.

  • Lorsque vous utilisez des sockets Web pour faire ce qui peut être fait via l'API Web, vous gardez toutes les connexions de tous les clients actifs ouvertes, ce qui n'est peut-être pas ce que vous voulez vraiment. Pour un petit site Web où vous vous attendez à avoir au plus 5 clients en même temps, ce n'est pas un problème. Pour un service comme Amazon AWS, cela ne serait pas facile à résoudre techniquement.

N'utilisez pas de sockets Web lorsque vous n'en avez pas besoin. Pour obtenir les coordonnées GPS d'une adresse, je ne gagne rien à ouvrir la connexion aux sockets Web, à passer l'appel, à attendre une réponse et à fermer la connexion: REST répond à mes besoins pour de tels scénarios.

  • Si vous vous retrouvez à plusieurs reprises et fréquemment à la recherche d'informations via un appel à un service REST, cela peut être un bon signe que vous devez passer aux sockets Web. De même, Stack Overflow réduit l'utilisation de la bande passante en utilisant sockets Web, car cela aide les gens à ne pas passer leur temps à appuyer sur F5 sur la page d'accueil pour voir s'ils ont de nouveaux messages.

  • Si vous constatez que vous ouvrez des connexions de sockets Web, utilisez-les pour effectuer un seul appel, puis fermez-les, ou si vos connexions restent ouvertes mais que le serveur envoie quelque chose au client uniquement à la demande du client, basculez vers REST.

De plus, les sockets web ont toujours un support limité et ne sont pas toujours faciles à implémenter. Bien que SignalR soit facile à implémenter, cela ne signifie pas que vous n'aurez aucune difficulté à l'implémenter dans d'autres langages/contextes/environnements. Avec REST, c'est simple: il peut s'agir d'un appel curl ou d'une fonctionnalité similaire disponible dans toutes les langues courantes. Avec les sockets Web, vous ne pouvez pas être sûr du temps qu'il faudrait pour qu'un client utilise [insérer ici le nom d'une langue que vous ne connaissez pas encore].

J'ai utilisé des sockets Web dans plusieurs projets en .NET, Python et node.js.

  • Dans .NET, ce n'était pas trop difficile, mais j'ai quand même passé quelques jours à essayer de comprendre certains problèmes cryptiques, tels que la connexion interrompue dès son ouverture. (C'était avant SignalR; je n'ai jamais essayé SignalR). J'ai également utilisé WCF en mode sockets Web, ce qui n'était pas sans problème non plus (mais je pense que WCF est toujours avec des problèmes).

  • Dans node.js, c'était faisable, mais j'ai dû changer deux fois de bibliothèque jusqu'à ce que j'en trouve une qui fonctionne. Je crois que j'ai passé au moins une semaine à essayer de créer un socket Hello World.

  • En Python, j'ai essayé une fois, j'ai passé deux ou trois jours et j'ai abandonné. Ça n'a jamais marché.

Comparez cela à REST: le seul problème que l'on peut rencontrer avec un nouveau langage/framework est de savoir comment POST fichiers ou recevoir une très grande réponse binaire. Je me souviens avoir passé quelques heures à chercher des solutions Pour certaines langues, quelques heures pour un cas particulier ne sont rien comparé à des jours ou des semaines pour un simple Hello World.

51
Arseni Mourzenko

Juste mes 2 cents ...

Je pense que ce n'est pas vraiment une question de performance ou quoi que ce soit. Il s'agit de normes. REST est un standard et à mon humble avis, les avantages suivants:

  • Les requêtes HTTP sont simples à utiliser. Tout le monde peut rapidement utiliser une API REST. Heck, vous pouvez même ouvrir le navigateur et taper une URL pour voir les données, comment pouvez-vous être plus interactif?
  • (Presque) n'importe quel langage de programmation peut l'utiliser. C'est une sorte d'interface universelle. L'interfaçage avec SignalR à partir d'un langage exotique semble moins évident.
  • Il a un support d'outillage agréable, comme http://petstore.swagger.wordnik.com/
  • C'est une belle "interface" à déboguer. Vous pouvez facilement surveiller les messages entrants et sortants directement dans le navigateur, voir les données, etc. Avec les sockets Web et les bibliothèques personnalisées, ce n'est pas aussi évident, vous devez tout enregistrer explicitement.
1
dagnelies