web-dev-qa-db-fra.com

Connexions/concentrateurs de signal multiples sur votre site Web

Si j'ai plusieurs pages pouvant utiliser plusieurs classes de concentrateur, quel est le meilleur moyen de gérer cela?

Par exemple:

  • Est-il mauvais de naviguer vers une autre page du site Web et essentiellement de "rouvrir" la connexion à la même classe de hub que celle ouverte à la page précédente?

  • Ai-je raison de penser que l'ouverture de plusieurs connexions de concentrateur sur une page est acceptable parce qu'elles sont toutes unifiées dans une même connexion, même si elles appartiennent à différentes classes de concentrateur?

17
anthonypliu

Vous pouvez avoir plusieurs concentrateurs partageant une connexion sur votre site. SignalR 2.0 a été mis à jour pour gérer plusieurs concentrateurs sur une seule connexion sans perte de performance.

Documents officiels: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#multiplehubs

Tous les clients utiliseront la même URL pour établir une connexion SignalR avec votre service ("/ signalr" ou votre URL personnalisée si vous en avez spécifié une), et cette connexion est utilisée pour tous les concentrateurs définis par le service.

Il n'y a que pas de différence de performances pour plusieurs concentrateurs par rapport à la définition de toutes les fonctionnalités de concentrateur dans une classe unique.

23
Sam

Pour commencer avec les hubs, lisez l’entrée WIKI pour les hubs et Côté client des hubs . Il y a plusieurs choses selon le contexte de plusieurs pages.

  1. Lorsque vous démarrez un concentrateur, il donne à votre client un ID qui reste identique pour ce concentrateur (quelqu'un peut confirmer avec un exemple) sur plusieurs pages.
  2. Ce n'est pas mal de rouvrir la connexion au même hub. Vous pouvez avoir une méthode côté client hub.start s'exécutant sur toutes les pages. Toutefois, si l'un de ses clients ouvre plusieurs fenêtres ou passe d'une page à une autre, vous aurez le même ID de connexion sur ce concentrateur afin que vous puissiez rester en contact. S'il s'agissait de plusieurs concentrateurs, vous devez gérer les concentrateurs ainsi que les identifiants de connexion. Cette question est donc la suivante: "Est-il mauvais que plusieurs fournisseurs de services Internet servent ma connexion Internet pour différents sites Web". Vous pouvez les avoir mais c'est exagéré. Un seul fournisseur de services Internet peut également gérer toutes les pages du serveur.
  3. La présence de plusieurs concentrateurs sur une seule page n’est pas idéale, mais cela fonctionnera. Encore une fois, la réponse nécessite un peu de contexte pour le problème, mais en général, vous pouvez différencier différentes demandes sur le même ID de connexion via des groupes ou en utilisant une autre approche basée sur des paramètres. Avoir deux concentrateurs sur la même page peut nécessiter plus de ressources (besoin de le tester) que d'utiliser des paramètres ou des groupes pour séparer différentes zones de messagerie.

Exemple:

Vous avez une page composée de deux parties, un graphique indiquant l'activité des utilisateurs en temps réel et une zone permettant d'afficher les modifications de données en temps réel effectuées par les utilisateurs sous forme de tableau. Allez-vous créer deux hubs ou deux groupes ou quoi? Il y a d'autres pages qui utilisent le même graphique et le même tableau de données.

Ma solution:

  1. Je vais créer un seul concentrateur pour que l'application reçoive des données en temps réel du serveur.
  2. Je vais créer différentes méthodes sur le serveur pour envoyer des points de graphique et des tableaux de données.
  3. Je vais créer une méthode côté client sur toutes les pages utilisant ces graphiques pour communiquer avec des méthodes serveur sur le même concentrateur.

Lorsque vous passez d'une page à l'autre, le client se connecte avec le même concentrateur et demande à getGraph ou getDataTable ou aux deux et remplit son client avec les données pertinentes. De même sur le serveur lorsque les données changent, vous pouvez appeler une méthode côté client pour mettre à jour tous les clients ou groupe de ceux-ci (ajoutons cette complexité)

Supposons que des étudiants et des enseignants examinent votre candidature. Ils nécessitent un niveau différent d'accès aux données. Vous pouvez utiliser des groupes pour les séparer sur le concentrateur afin que vous n'envoyiez pas d'informations d'enseignants aux étudiants et que les données des étudiants aux enseignants.

  1. Sur votre participation au hub, vous pouvez les ajouter pour rejoindre un groupe associé à leur rôle ou à une fonction de différenciation.
  2. Lorsque vous envoyez des messages à tous les clients, vous pouvez désormais les envoyer à un groupe de clients, enseignants ou étudiants. Ne créant pas un autre hub pour les enseignants ou les étudiants, ils sont tous sur le même hub.

Pour revenir à votre question "est-ce mauvais" et "est-ce correct", il est difficile à établir sans contexte d'application réelle. Je ne peux pas penser à un scénario dans lequel vous pouvez justifier plusieurs concentrateurs en plus de Performance .

9
Farrukh Subhani

SignalR Core - NON POSSIBLE

Malheureusement, ce n'est plus possible dans la nouvelle version "Core" de SignalR

https://github.com/aspnet/SignalR/issues/456

https://github.com/aspnet/SignalR/issues/955


Notes: Problèmes avec iOS et les certificats auto-signés

Sur iOS, le nombre de connexions par serveur est limité à QUATRE.

Maintenant, il n'y a pas cette limite pour les websockets (je pense que ce peut être 32 mais pas sûr). Cependant j'utilise un certificat auto-signé qui pose toutes sortes de problèmes dans Safari - il ne reste donc plus qu'une longue interrogation (et ce n'est pas évident que ce soit fait). 

Alors j'ai fini avec ces connexions:

  • 1 - Socket Angular/Webpack Hot Reload
  • 2 - Appels API Web
  • 3 - Hub numéro un
  • 4 - Hub numéro deux
  • 5 - #& # & # $ & # $ &

Donc, si je n'avais que trois hubs, toute la page Safari serait verrouillée par une barre bleue. Même les appels d'API Web ont été bloqués.

Remarque: avec HTTP/2 cette limite a disparu mais vous feriez mieux de vous limiter à un concentrateur, surtout si vous utilisez le rechargement à chaud. De plus, configurer HTTP/2 en développement n'est pas nécessairement une tâche triviale.


Alors, comment réparer?

D'abord (temporairement) configurez votre hub pour n'accepter que les websockets. Cela vous donnera une erreur dans Safari (assurez-vous que les erreurs sont interceptées et affichées dans une boîte de dialogue d'alerte).

routes.MapHub<SignalRHub>("/rt", options =>
{
     // when run in debug mode only WebSockets are allowed
     if (Debugger.IsAttached) {
        options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
     }
});

Vous pourrez maintenant confirmer le correctif - exécuter en mode débogage ou supprimer le 'if'.

Le problème avec iOS est que même si vous acceptez un certificat auto-signé pour le trafic https - et obtenez un joli petit symbole 'verrouillé' dans le navigateur - cela ne s'applique pas au protocole wss:. Les connexions ne peuvent donc pas être mises à niveau à wss, raison pour laquelle elles bloquent au maximum 4.

Solution n ° 1

Si vous pouvez tout obtenir sur un hub, c'est plus simple :-)

J'ai également réalisé que plusieurs concentrateurs compliquent la logique de reconnexion en cas de perte de la connexion. Un hub rend cela plus facile. Si vous ne faites pas attention, vous allez finir par afficher 3 boîtes de dialogue disant «Connexion perdue. Réessayez?' Je passe à un seul hub simplement pour cette raison.

Bien que je déteste tout mélanger, les classes partielles m'aident et je n'ai personnellement pas beaucoup de méthodes SignalR de toute façon.

Solution n ° 2

Cela concerne uniquement le débogage et suppose que vous utilisez un certificat https que vous avez auto-signé.

Utilisez à la place quelque chose comme letsencrypt ou le tunnel argo de Cloudflare pour obtenir un certificat de confiance publique. Safari aura entièrement confiance en cela, de sorte que vos connexions seront mises à niveau vers de véritables sockets Web.

Solution n ° 3

Créez un certificat ROOT auto-signé, puis générez des certificats SSL avec le nom de domaine.

C'était plus compliqué que ce que j'avais imaginé. À la fin, il est apparu que je manquais de Subject Type=CA dans mon certificat racine, ce qui est nécessaire pour iOS. Sans cette "extension", il installera le certificat racine en tant que profil, mais ne vous permettra pas de le sélectionner pour SSL.

Une fois le certificat racine installé, Safari fonctionnera parfaitement avec les Websockets.

Solution n ° 4

Utilisez http uniquement. Ce n'était pas une option pour moi parce que j'utilise certaines API comme Facebook/Google/Paiement et qu'elles nécessitent https.

Remarques

  • Important: Considérons maintenant la production. Sachez que les Websockets peuvent ne pas être disponibles pour différentes raisons. Par conséquent, si vous avez 4 concentrateurs connectés sur iOS, cela peut toujours entraîner un blocage. Tu vis dangereusement. 

Mieux vaut utiliser un hub en premier lieu. MAIS il est également préférable d’installer votre CERT correctement afin que iOS fonctionne avec les Websockets.

Comment créer et installer des certificats auto-signés X.509 dans Windows 10 sans interaction de l'utilisateur?

2
Simon_Weaver