Introduction à SignalR

par Patrick Fletcher

Avertissement

Cette documentation ne concerne pas la dernière version de SignalR. Consultez ASP.NET Core SignalR.

Cet article décrit ce qu’est SignalR et certaines des solutions qu’il a été conçu pour créer.

Questions et commentaires

Laissez vos commentaires sur la façon dont vous avez aimé ce tutoriel et sur ce que nous pourrions améliorer dans les commentaires en bas de la page. Si vous avez des questions qui ne sont pas directement liées au tutoriel, vous pouvez les publier sur le forum ASP.NET SignalR ou StackOverflow.com.

Qu’est-ce que SignalR ?

ASP.NET SignalR est une bibliothèque destinée aux développeurs ASP.NET qui simplifie le processus d’ajout de fonctionnalités web en temps réel aux applications. La fonctionnalité web en temps réel est la possibilité d’avoir du contenu push du code serveur vers les clients connectés instantanément à mesure qu’il devient disponible, plutôt que de laisser le serveur attendre qu’un client demande de nouvelles données.

SignalR peut être utilisé pour ajouter n’importe quelle fonctionnalité web en temps réel à votre application ASP.NET. Bien que la conversation soit souvent utilisée comme exemple, vous pouvez en faire beaucoup plus. Chaque fois qu’un utilisateur actualise une page web pour voir de nouvelles données, ou que la page implémente une longue interrogation pour récupérer de nouvelles données, il est candidat à l’utilisation de SignalR. Les exemples incluent les tableaux de bord et les applications de surveillance, les applications collaboratives (telles que la modification simultanée de documents), les mises à jour de la progression des travaux et les formulaires en temps réel.

SignalR active également de nouveaux types d’applications web qui nécessitent des mises à jour à haute fréquence du serveur, par exemple des jeux en temps réel.

SignalR fournit une API simple pour créer des appels de procédure distante (RPC) serveur à client qui appellent des fonctions JavaScript dans les navigateurs clients (et d’autres plateformes clientes) à partir de code .NET côté serveur. SignalR inclut également l’API pour la gestion des connexions (pour les événements instance, de connexion et de déconnexion) et le regroupement des connexions.

Appel de méthodes avec SignalR

SignalR traite automatiquement la gestion des connexions et vous permet de diffuser des messages à tous les clients connectés simultanément, comme une salle de conversation. Vous pouvez également envoyer des messages à des clients spécifiques. La connexion entre le client et le serveur est permanente, contrairement à une connexion HTTP classique qui est rétablie pour chaque communication.

SignalR prend en charge la fonctionnalité « server push », dans laquelle le code serveur peut appeler le code client dans le navigateur à l’aide d’appels de procédure distante (RPC), plutôt que le modèle de demande-réponse courant sur le web aujourd’hui.

Les applications SignalR peuvent effectuer un scale-out sur des milliers de clients à l’aide de fournisseurs de scale-out intégrés et tiers.

Les fournisseurs intégrés sont les suivants :

Les fournisseurs tiers incluent :

SignalR est open source, accessible via GitHub.

SignalR et WebSocket

SignalR utilise le nouveau transport WebSocket lorsqu’il est disponible et revient aux anciens transports si nécessaire. Bien que vous puissiez certainement écrire votre application directement à l’aide de WebSocket, l’utilisation de SignalR signifie qu’une grande partie des fonctionnalités supplémentaires que vous devez implémenter est déjà effectuée pour vous. Plus important encore, cela signifie que vous pouvez coder votre application pour tirer parti de WebSocket sans avoir à vous soucier de la création d’un chemin de code distinct pour les clients plus anciens. SignalR vous empêche également d’avoir à vous soucier des mises à jour de WebSocket, car SignalR est mis à jour pour prendre en charge les modifications du transport sous-jacent, ce qui fournit à votre application une interface cohérente entre les versions de WebSocket.

Transports et secours

SignalR est une abstraction sur certains des transports nécessaires pour effectuer un travail en temps réel entre le client et le serveur. SignalR tente d’abord d’établir une connexion WebSocket si possible. WebSocket est le transport optimal pour SignalR, car il a :

  • Utilisation la plus efficace de la mémoire du serveur.
  • Latence la plus faible.
  • Fonctionnalités les plus sous-jacentes, telles que la communication duplex intégral entre le client et le serveur.
  • Les exigences les plus strictes, WebSocket nécessite le serveur :
    • Exécutez sur Windows Server 2012 ou Windows 8.
    • .NET Framework 4.5.

Si ces conditions ne sont pas remplies, SignalR tente d’utiliser d’autres transports pour établir ses connexions.

Transports HTML 5

Ces transports dépendent de la prise en charge de HTML 5. Si le navigateur client ne prend pas en charge la norme HTML 5, des transports plus anciens seront utilisés.

  • WebSocket (si le serveur et le navigateur indiquent qu’ils peuvent prendre en charge Websocket). WebSocket est le seul transport qui établit une véritable connexion bidirectionnelle permanente entre le client et le serveur. Toutefois, WebSocket a également les exigences les plus strictes; il est entièrement pris en charge uniquement dans les dernières versions de Microsoft Internet Explorer, Google Chrome et Mozilla Firefox, et n’a qu’une implémentation partielle dans d’autres navigateurs tels que Opera et Safari.
  • Événements envoyés de serveur, également appelés EventSource (si le navigateur prend en charge les événements server sent, qui sont essentiellement tous les navigateurs à l’exception d’Internet Explorer.)

Transports comet

Les transports suivants sont basés sur le modèle d’application web Comet , dans lequel un navigateur ou un autre client gère une requête HTTP de longue durée, que le serveur peut utiliser pour envoyer des données au client sans que le client ne la demande spécifiquement.

  • Forever Frame (pour Internet Explorer uniquement). Forever Frame crée un IFrame masqué qui effectue une requête à un point de terminaison sur le serveur qui ne se termine pas. Le serveur envoie ensuite continuellement un script au client qui est immédiatement exécuté, ce qui fournit une connexion en temps réel unidirectionnel entre le serveur et le client. La connexion entre le client et le serveur utilise une connexion distincte du serveur au client et, comme une requête HTTP standard, une nouvelle connexion est créée pour chaque élément de données qui doit être envoyé.
  • Interrogation longue Ajax. L’interrogation longue ne crée pas de connexion persistante, mais interroge le serveur avec une requête qui reste ouverte jusqu’à ce que le serveur réponde, à quel moment la connexion se ferme et qu’une nouvelle connexion est demandée immédiatement. Cela peut introduire une certaine latence pendant la réinitialisation de la connexion.

Pour plus d’informations sur les transports pris en charge sous quelles configurations, consultez Plateformes prises en charge.

Processus de sélection du transport

La liste suivante montre les étapes utilisées par SignalR pour déterminer le transport à utiliser.

  1. Si le navigateur est Internet Explorer 8 ou version antérieure, l’interrogation longue est utilisée.

  2. Si JSONP est configuré (autrement dit, le jsonp paramètre est défini sur true au démarrage de la connexion), l’interrogation longue est utilisée.

  3. Si une connexion inter-domaines est établie (autrement dit, si le point de terminaison SignalR ne se trouve pas dans le même domaine que la page d’hébergement), WebSocket est utilisé si les critères suivants sont remplis :

    • Le client prend en charge CORS (Cross-Origin Resource Sharing). Pour plus d’informations sur les clients qui prennent en charge CORS, consultez CORS sur caniuse.com.

    • Le client prend en charge WebSocket

    • Le serveur prend en charge WebSocket

      Si l’un de ces critères n’est pas rempli, l’interrogation longue est utilisée. Pour plus d’informations sur les connexions inter-domaines, consultez Comment établir une connexion inter-domaines.

  4. Si JSONP n’est pas configuré et que la connexion n’est pas inter-domaines, WebSocket sera utilisé si le client et le serveur le prennent en charge.

  5. Si le client ou le serveur ne prennent pas en charge WebSocket, les événements envoyés du serveur sont utilisés s’ils sont disponibles.

  6. Si les événements envoyés du serveur ne sont pas disponibles, l’option Frame forever est tentée.

  7. Si Forever Frame échoue, l’interrogation longue est utilisée.

Surveillance des transports

Vous pouvez déterminer le transport utilisé par votre application en activant la journalisation sur votre hub et en ouvrant la fenêtre de console dans votre navigateur.

Pour activer la journalisation des événements de votre hub dans un navigateur, ajoutez la commande suivante à votre application cliente :

$.connection.hub.logging = true;

  • Dans Internet Explorer, ouvrez les outils de développement en appuyant sur F12, puis cliquez sur l’onglet Console.

    Console dans Microsoft Internet Explorer

  • Dans Chrome, ouvrez la console en appuyant sur Ctrl+Maj+J.

    Console dans Google Chrome

Une fois la console ouverte et la journalisation activée, vous pouvez voir quel transport est utilisé par SignalR.

Console dans Internet Explorer montrant le transport WebSocket

Spécification d’un transport

La négociation d’un transport prend un certain temps et des ressources client/serveur. Si les fonctionnalités du client sont connues, un transport peut être spécifié lorsque la connexion cliente est démarrée. L’extrait de code suivant illustre le démarrage d’une connexion à l’aide du transport Ajax Long Polling, comme serait utilisé s’il était connu que le client ne prenait pas en charge aucun autre protocole :

connection.start({ transport: 'longPolling' });

Vous pouvez spécifier une commande de secours si vous souhaitez qu’un client essaie des transports spécifiques dans l’ordre. L’extrait de code suivant illustre l’essai de WebSocket et, à défaut, l’accès direct à l’interrogation longue.

connection.start({ transport: ['webSockets','longPolling'] });

Les constantes de chaîne permettant de spécifier des transports sont définies comme suit :

  • webSockets
  • foreverFrame
  • serverSentEvents
  • longPolling

Connexions et hubs

L’API SignalR contient deux modèles de communication entre les clients et les serveurs : connexions permanentes et hubs.

Une connexion représente un point de terminaison simple pour l’envoi de messages à destinataire unique, groupés ou de diffusion. L’API connexion permanente (représentée dans le code .NET par la classe PersistentConnection) donne au développeur un accès direct au protocole de communication de bas niveau exposé par SignalR. L’utilisation du modèle de communication Connections est familière aux développeurs qui ont utilisé des API basées sur la connexion telles que Windows Communication Foundation.

Un hub est un pipeline de niveau supérieur basé sur l’API de connexion qui permet à votre client et à votre serveur d’appeler des méthodes l’un sur l’autre directement. SignalR gère la répartition au-delà des limites de la machine comme par magie, ce qui permet aux clients d’appeler des méthodes sur le serveur aussi facilement que les méthodes locales, et vice versa. L’utilisation du modèle de communication Hubs est familière aux développeurs qui ont utilisé des API d’appel à distance telles que la communication à distance .NET. L’utilisation d’un hub vous permet également de passer des paramètres fortement typés à des méthodes, ce qui permet la liaison de modèle.

Diagramme de l'architecture

Le diagramme suivant montre la relation entre les hubs, les connexions permanentes et les technologies sous-jacentes utilisées pour les transports.

Diagramme de l’architecture SignalR montrant les API, les transports et les clients

Fonctionnement des hubs

Lorsque le code côté serveur appelle une méthode sur le client, un paquet est envoyé sur le transport actif qui contient le nom et les paramètres de la méthode à appeler (lorsqu’un objet est envoyé en tant que paramètre de méthode, il est sérialisé à l’aide de JSON). Le client fait ensuite correspondre le nom de la méthode aux méthodes définies dans le code côté client. S’il existe une correspondance, la méthode cliente est exécutée à l’aide des données de paramètre désérialisées.

L’appel de méthode peut être surveillé à l’aide d’outils tels que Fiddler. L’image suivante montre un appel de méthode envoyé à partir d’un serveur SignalR à un client de navigateur web dans le volet Journaux de Fiddler. L’appel de méthode est envoyé à partir d’un hub appelé MoveShapeHub, et la méthode appelée est appelée updateShape.

Affichage du journal Fiddler montrant le trafic SignalR

Dans cet exemple, le nom du hub est identifié avec le H paramètre ; le nom de la méthode est identifié avec le M paramètre et les données envoyées à la méthode sont identifiées avec le A paramètre . L’application qui a généré ce message est créée dans le didacticiel en temps réel haute fréquence .

Choix d’un modèle de communication

La plupart des applications doivent utiliser l’API Hubs. L’API Connections peut être utilisée dans les circonstances suivantes :

  • Le format du message envoyé doit être spécifié.
  • Le développeur préfère utiliser un modèle de messagerie et de distribution plutôt qu’un modèle d’appel à distance.
  • Une application existante qui utilise un modèle de messagerie est en cours de portage pour utiliser SignalR.