Share via


Guide de dépannage pour résoudre des problèmes courants rencontrés avec Azure SignalR Service

Cet article fournit des conseils de résolution des problèmes pour certains problèmes courants rencontrés par les clients.

Jeton d’accès trop long

Erreurs possibles

  • ERR_CONNECTION_ côté client
  • 414 URI trop long
  • 413 Payload Too Large
  • La longueur du jeton d’accès ne doit pas dépasser 4 Ko. 413 Entité de demande trop grande

Origine

Pour HTTP/2, la longueur maximale d’un en-tête est de 4 K. Par conséquent, si vous utilisez un navigateur pour accéder au service Azure, cette limitation génèrera une erreur ERR_CONNECTION_.

Pour les clients HTTP/1.1 ou C#, la longueur maximale de l’URI est de 12 K, et la longueur maximale de l’en-tête de 16 K.

Avec le Kit de développement logiciel (SDK) versions 1.0.6 ou supérieures, /negotiate lève l’erreur 413 Payload Too Large quand le jeton d’accès généré est d’une longueur supérieure à 4 K.

Solution

Par défaut, les revendications de context.User.Claims sont incluses lors de la génération du jeton d’accès JWT pour ASRS (Azure SignalRService). Ainsi, les revendications sont conservées et peuvent être transmises d’ASRS au Hub lorsque le client se connecte au Hub.

Dans certains cas, des revendications context.User.Claims sont utilisées pour stocker de grandes quantités d’informations pour le serveur d’applications, dont la plupart ne sont pas utilisées par les Hubs mais par d’autres composants.

Le jeton d’accès généré est transmis via le réseau et, pour les connexions WebSocket/SSE, les jetons d’accès sont transmis via des chaînes de requête. C’est pourquoi nous recommandons de transmettre les revendications nécessaires du client via ASRS à votre serveur d’applications quand le Hub en a besoin.

ClaimsProvider vous permet de personnaliser les revendications transmises à ASRS dans le jeton d’accès.

Pour ASP.NET Core :

services.AddSignalR()
        .AddAzureSignalR(options =>
            {
                // pick up necessary claims
                options.ClaimsProvider = context => context.User.Claims.Where(...);
            });

Pour ASP.NET :

services.MapAzureSignalR(GetType().FullName, options =>
            {
                // pick up necessary claims
                options.ClaimsProvider = context.Authentication?.User.Claims.Where(...);
            });

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

TLS 1.2 requis

Erreurs possibles

  • ASP.NET « Aucun serveur disponible » erreur #279
  • ASP.NET « La connexion n’est pas active. Impossible d’envoyer des données au service. » erreur #324
  • « Une erreur s’est produite lors de l’envoi de la requête HTTP à https://<API endpoint>. Cette erreur peut être due au fait que le certificat de serveur n’est pas configuré correctement avec HTTP.SYS pour HTTPS. Une autre cause possible de cette erreur est une non-correspondance de la liaison de sécurité entre le client et le serveur. »

Origine

Le service Azure prend uniquement en charge le protocole TLS 1.2 pour les problèmes de sécurité. Avec .NET Framework, il est possible que le protocole par défaut ne soit pas TLS 1.2. Par conséquent, les connexions du serveur à ASRS ne peuvent pas être établies.

Guide de résolution des problèmes

  1. Si cette erreur peut être reproduite localement, désactivez l’option Uniquement mon code et levez toutes les exceptions CLR, puis déboguez le serveur d’applications localement pour voir les levées d’exceptions.

    • Désactive l’option Uniquement mon code

      Uncheck Just My Code

    • Lever des exceptions CLR

      Throw CLR exceptions

    • Consultez la levée d’exceptions lors du débogage du code côté serveur d’applications :

      Exception throws

  2. Pour les exceptions ASP.NET, vous pouvez également ajouter le code suivant à votre Startup.cs pour activer la trace détaillée et voir les erreurs du journal.

    app.MapAzureSignalR(this.GetType().FullName);
    // Make sure this switch is called after MapAzureSignalR
    GlobalHost.TraceManager.Switch.Level = SourceLevels.Information;
    

Solution

Ajoutez le code suivant à votre démarrage :

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

400 Requête incorrecte retournée aux demandes du client

Origine

Vérifiez si la demande de votre client comporte plusieurs chaînes de requête hub. hub est un paramètre de requête préservé et 400 lève une exception si le service détecte plus d’un hub dans la requête.

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

Code 401 - Non autorisé retourné pour les demandes des clients

Origine

Actuellement, la valeur par défaut de la durée de vie du jeton JWT est d’une heure (1).

OK pour ASP.NET Core SignalR avec le type de transport WebSocket.

Pour un autre type de transport, un SSE et une interrogation longue d’ASP.NET Core SignalR, cette durée de vie par défaut signifie que la connexion peut persister par défaut une heure maximum.

Pour ASP.NET SignalR, le client envoie une demande « keep alive » /ping au service de temps en temps. Quand le /ping échoue, le client abandonne la connexion et ne se reconnecte jamais. Pour ASP.NET SignalR, la durée de vie du jeton par défaut fait durer la connexion au maximum pendant une heure pour tous les types de transport.

Solution

Par souci de sécurité, il n’est pas recommandé d’étendre le protocole TTL. Nous vous suggérons d’ajouter une logique de reconnexion à partir du client pour redémarrer la connexion quand une telle erreur 401 se produit. Lorsque le client redémarre la connexion, il négocie avec le serveur d’applications pour obtenir à nouveau le jeton JWT et obtenir un jeton renouvelé.

Pour savoir comment redémarrer des connexions client, voir ici.

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

Code 404 retourné pour les demandes des clients

Une connexion persistante SignalR commence par négocier (/negotiate) l’accès au Azure SignalR Service, puis établit la connexion réelle à Azure SignalR Service.

Guide de résolution des problèmes

  • Voici Comment afficher des demandes sortantes pour obtenir la demande du client au service.
  • Vérifiez l’URL de la demande quand l’erreur 404 se produit. Si l’URL cible votre application web, et est similaire à {your_web_app}/hubs/{hubName}, vérifiez si la valeur de SkipNegotiation du client est true. Le client reçoit l’URL de redirection quand il négocie pour la première fois avec le serveur d’applications. Le client ne doit pas ignorer la négociation lors de l’utilisation d’Azure SignalR.
  • Une autre erreur 404 peut se produire quand la demande de connexion est traitée plus de cinq (5) secondes après l’appel de /negotiate. Vérifiez l’horodatage de la demande client, puis ouvrez un problème chez nous si la réponse à la demande adressée au service est lente.

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

Erreur 404 retournée pour la demande de reconnexion d’ASP.NET SignalR

Pour ASP.NET SignalR, en cas d’interruption de la connexion client, celle-ci est rétablie à l’aide du même connectionId à trois reprises avant son arrêt. Le commande /reconnect peut être utile si la connexion est interrompue en raison de problèmes intermittents du réseau et que la commande /reconnect peut rétablir correctement la connexion persistante. Dans d’autres circonstances, par exemple, si la connexion client est interrompue en raison de la perte de la connexion serveur routée, ou parce que le service SignalR rencontre des erreurs internes telles qu’un redémarrage/basculement/déploiement d’instance, la connexion cesse d’exister et la commande /reconnect retourne l’erreur 404. Il s’agit du comportement attendu de la commande /reconnect. Après trois nouvelles tentatives, la connexion s’arrête. Nous vous suggérons de vous doter d’une logique de redémarrage de connexion lorsque la connexion s’arrête.

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

Erreur 429 (Trop de demandes) retournée aux demandes client

Il existe deux cas.

Le nombre de connexions simultanées dépasse la limite

Pour des instances Gratuites, la limite du nombre de connexions simultanées est de 20. Pour des instances Standard, la limite du nombre de connexions simultanéespar unité est de 1 K, ce qui signifie que Unit100 autorise 100 000 connexions simultanées.

Les connexions incluent les connexions client et serveur. Pour savoir comment les connexions sont comptées, voir ici.

Trop de demandes de négociation simultanées

Nous vous suggérons d’avoir un délai aléatoire avant de vous reconnecter, consultez ici pour les exemples de nouvelles tentatives.

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

500 Erreur lors de la négociation : Azure SignalR Service n’est pas encore connecté. Réessayez plus tard.

Origine

Cette erreur est signalée quand il n’existe aucune connexion serveur à Azure SignalR Service.

Guide de résolution des problèmes

Activez la trace côté serveur pour connaître les détails de l’erreur lorsque le serveur tente de se connecter à Azure SignalR Service.

Activer la journalisation côté serveur pour ASP.NET Core SignalR

La journalisation côté serveur pour ASP.NET Core SignalR s’intègre avec la journalisation basée sur ILogger fournie dans le framework ASP.NET Core. Vous pouvez activer la journalisation côté serveur à l’aide de ConfigureLogging, un exemple d’utilisation comme suit :

.ConfigureLogging((hostingContext, logging) =>
        {
            logging.AddConsole();
            logging.AddDebug();
        })

Les catégories d’enregistreur d’événements pour Azure SignalR commencent toujours par Microsoft.Azure.SignalR. Pour activer les journaux détaillés d’Azure SignalR, configurez les préfixes précédents sur le niveau Debug dans votre fichier appsettings.json comme ci-dessous :

{
    "Logging": {
        "LogLevel": {
            ...
            "Microsoft.Azure.SignalR": "Debug",
            ...
        }
    }
}

Activer les traces côté serveur pour ASP.NET SignalR

En cas d’utilisation d’une version du Kit de développement logiciel (SDK) >= 1.0.0, vous pouvez activer les traces en ajoutant le code suivant au fichier web.config : (Détails).

<system.diagnostics>
    <sources>
      <source name="Microsoft.Azure.SignalR" switchName="SignalRSwitch">
        <listeners>
          <add name="ASRS" />
        </listeners>
      </source>
    </sources>
    <!-- Sets the trace verbosity level -->
    <switches>
      <add name="SignalRSwitch" value="Information" />
    </switches>
    <!-- Specifies the trace writer for output -->
    <sharedListeners>
      <add name="ASRS" type="System.Diagnostics.TextWriterTraceListener" initializeData="asrs.log.txt" />
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

Pertes de connexion client

Lorsque le client est connecté à Azure SignalR, la connexion persistante entre le client et Azure SignalR peut parfois s’interrompre pour différentes raisons. Cette section décrit plusieurs causes possibles d’une telle perte de connexion et fournit des conseils sur la façon d’identifier la cause racine.

Erreurs possibles côté client

  • The remote party closed the WebSocket connection without completing the close handshake
  • Service timeout. 30000.00ms elapsed without receiving a message from service.
  • {"type":7,"error":"Connection closed with an error."}
  • {"type":7,"error":"Internal server error."}

Origine

Les connexions client peuvent être interrompues dans diverses circonstances :

  • Quand Hub lève des exceptions avec la demande entrante
  • Quand la connexion serveur vers laquelle le client est routé s’interrompt, consultez la section ci-dessous pour plus de détails sur les pertes de connexion serveur
  • Quand un problème de connectivité réseau se produit entre le client et SignalR Service
  • Quand SignalR Service rencontre des erreurs internes, par exemple de redémarrage, de basculement ou de déploiement d’instance, etc.

Guide de résolution des problèmes

  1. Ouvrez le journal côté serveur d’applications pour voir si quelque chose d’anormal s’est produit.
  2. Vérifiez le journal des événements côté serveur d’applications pour voir si le serveur d’applications a redémarré.
  3. Ouvrez un problème chez nous en fournissant le laps de temps, et envoyez-nous par e-mail le nom de la ressource.

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

La connexion client augmente constamment

Cela peut être dû à une utilisation incorrecte de la connexion client. Si quelqu’un oublie d’arrêter ou de supprimer le client SignalR, la connexion reste ouverte.

Erreurs possibles observées dans les métriques de SignalR, dans la section Surveillance du menu de ressources du portail Azure

Les connexions client augmentent constamment pendant une longue période dans les métriques d’Azure SignalR.

Client connection increasing constantly

Origine

Commande DisposeAsync de la connexion client SignalR jamais appelée. La connexion reste ouverte.

Guide de résolution des problèmes

Vérifiez si le client SignalR ne se ferme jamais.

Solution

Vérifiez si vous fermez la connexion. Appelez manuellement la commande HubConnection.DisposeAsync() pour arrêter la connexion après l’avoir utilisée.

Par exemple :

var connection = new HubConnectionBuilder()
	.WithUrl(...)
	.Build();
try
{
	await connection.StartAsync();
	// Do your stuff
	await connection.StopAsync();
}
finally
{
	await connection.DisposeAsync();
}

Utilisation incorrecte courante de la connexion client

Exemple de fonction Azure

Ce problème se produit souvent quand un utilisateur établit une connexion client SignalR dans une méthode de fonction Azure au lieu d’en faire un membre statique de la classe de fonction. Vous vous attendez peut-être à ce qu’une seule connexion client soit établie, mais vous constatez au contraire que le nombre de connexions client augmente constamment dans les métriques. Toutes ces connexions sont annulées uniquement après le redémarrage de la fonction Azure ou du service Azure SignalR. Cela est dû au fait que pour chaque demande, la fonction Azure crée une connexion client. Si vous n’arrêtez pas la connexion client dans la méthode de fonction, le client conserve les connexions actives au service Azure SignalR.

Solution

  • N’oubliez pas de fermer la connexion client si vous utilisez des clients SignalR dans une fonction Azure ou si vous utilisez un client SignalR en tant que singleton.
  • Au lieu d’utiliser des clients SignalR dans une fonction Azure, vous pouvez créer des clients SignalR partout ailleurs et utiliser des Liaisons Azure Functions pour Azure SignalR Service afin de négocier l’accès du client à Azure SignalR. Vous pouvez également utiliser la liaison pour envoyer des messages. Vous trouverez des exemples pour négocier l’accès du client et envoyer des messages ici. Des informations supplémentaires sont disponibles ici.
  • Lorsque vous utilisez des clients SignalR dans une fonction Azure Function, il peut y avoir une meilleure architecture à votre scénario. Vérifiez si vous concevez une architecture sans serveur appropriée. Vous pouvez vous référer à Applications sans serveur en temps réel avec les liaisons SignalR Service dans Azure Functions.

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

Pertes de connexion serveur

Au démarrage du serveur d’applications, en arrière-plan, le Kit de développement logiciel (SDK) Azure commence à initier des connexions serveur à l’Azure SignalR distant. Comme décrit dans Éléments internes d’Azure SignalR Service, Azure SignalR achemine les trafics clients entrants vers ces connexions serveur. Une fois qu’une connexion serveur est interrompue, toutes les connexions client qu’elle dessert sont également fermées.

Les connexions entre le serveur d’applications et SignalR Service étant persistantes, elles peuvent rencontrer des problèmes de connectivité réseau. Dans le kit SDK Serveur, nous avons une stratégie Toujours se reconnecter pour les connexions serveur. La meilleure pratique consiste à ajouter une logique de reconnexion continue aux clients avec un délai aléatoire afin d’éviter l’envoi d’une quantité massive de demandes simultanées au serveur.

De nouvelles versions d’Azure SignalR Service sont publiées régulièrement, ainsi que des mises à jour correctives ou des mises à niveau à l’échelle d’Azure, qui interrompent occasionnellement nos services dépendants. Ces événements peuvent entraîner une courte interruption des services. Toutefois, tant que le mécanisme de déconnexion/reconnexion fonctionne côté client, l’effet est minime, comme toute déconnexion/reconnexion côté client.

Cette section décrit plusieurs causes possibles de perte de connexion serveur, et fournit des conseils sur la façon d’identifier la cause racine.

Erreurs possibles côté serveur

  • [Error]Connection "..." to the service was dropped
  • The remote party closed the WebSocket connection without completing the close handshake
  • Service timeout. 30000.00ms elapsed without receiving a message from service.

Origine

La connexion serveur-service est fermée par ASRS (Azure SignalRService).

Pour le délai d’expiration du test Ping, cela peut être dû à une utilisation élevée du processeur ou une insuffisance du pool de threads côté serveur.

Pour SignalR ASP.NET, un problème connu a été résolu dans le Kit de développement logiciel (SDK) 1.6.0. Mettez à niveau votre Kit de développement logiciel (SDK) vers la version la plus récente.

Insuffisance du pool de threads

Si votre serveur rencontre une insuffisance, cela signifie qu’aucun thread ne traite de messages. Tous les threads ne répondent pas dans une certaine méthode.

Ce scénario est normalement provoqué par Async sur Sync ou par Task.Result/Task.Wait() dans les méthodes asynchrones.

Consultez Meilleures pratiques d’ASP.NET Core en matière de performances.

Apprenez-en davantage sur l’insuffisance du pool de threads.

Comment détecter une insuffisance du pool de threads

Vérifiez le nombre de threads. S’il n’y a pas de pics à ce stade, effectuez les étapes suivantes :

  • Si vous utilisez Azure App Service, vérifiez le nombre de threads dans les métriques. Vérifiez l’agrégation Max :

    Screenshot of the Max thread count pane in Azure App Service.

  • Si vous utilisez .NET Framework, vous pouvez trouver des métriques dans l’Analyseur de performances de votre machine virtuelle serveur.

  • Si vous utilisez .NET Core dans un conteneur, consultez Collecter les diagnostics dans des conteneurs.

Vous pouvez également utiliser du code pour détecter une insuffisance du pool de threads :

public class ThreadPoolStarvationDetector : EventListener
{
    private const int EventIdForThreadPoolWorkerThreadAdjustmentAdjustment = 55;
    private const uint ReasonForStarvation = 6;

    private readonly ILogger<ThreadPoolStarvationDetector> _logger;

    public ThreadPoolStarvationDetector(ILogger<ThreadPoolStarvationDetector> logger)
    {
        _logger = logger;
    }

    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        if (eventSource.Name == "Microsoft-Windows-DotNETRuntime")
        {
            EnableEvents(eventSource, EventLevel.Informational, EventKeywords.All);
        }
    }

    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        // See: https://learn.microsoft.com/dotnet/framework/performance/thread-pool-etw-events#threadpoolworkerthreadadjustmentadjustment
        if (eventData.EventId == EventIdForThreadPoolWorkerThreadAdjustmentAdjustment &&
            eventData.Payload[2] as uint? == ReasonForStarvation)
        {
            _logger.LogWarning("Thread pool starvation detected!");
        }
    }
}

Ajoutez-le à votre service :

service.AddSingleton<ThreadPoolStarvationDetector>();

Vérifiez ensuite votre journal lorsque la connexion au serveur est déconnectée par le délai d’expiration du test Ping.

Comment trouver la cause racine de l’insuffisance du pool de threads

Pour trouver la cause racine de l’insuffisance du pool de threads :

  • Videz la mémoire, puis analysez la pile des appels. Pour plus d’informations, consultez Collecter et analyser les vidages de mémoire.
  • Utilisez clrmd pour vider la mémoire lorsque l’insuffisance du pool de threads est détectée. Consignez ensuite la pile des appels.

Guide de résolution des problèmes

  1. Ouvrez le journal côté serveur d’applications pour voir si quelque chose d’anormal s’est produit.
  2. Vérifiez le journal des événements côté serveur d’applications pour voir si le serveur d’applications a redémarré.
  3. Créez un problème. Fournissez le laps de temps et envoyez-nous par e-mail le nom de la ressource.

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

Conseils

Comment afficher la demande sortante du client ?

Prenons ASP.NET Core par exemple (ASP.NET est similaire) :

  • Dans le navigateur : Prenons l’exemple de Chrome. Vous pouvez utiliser la touche F12 pour ouvrir la fenêtre de console, puis passer à l’onglet Réseau. Vous devrez peut-être actualiser la page à l’aide de F5 pour capturer le réseau depuis le tout début.

    Chrome View Network

  • À partir d’un client C# :

    Vous pouvez afficher les trafics web locaux à l’aide de Fiddler. Les trafics WebSocket sont pris en charge depuis Fiddler version 4.5.

    Fiddler View Network

Comment redémarrer une connexion client ?

Voici les exemples de code contenant une logique de redémarrage de connexion avec une stratégie TOUJOURS RÉESSAYER :

Vous avez des problèmes ou des commentaires sur la résolution des problèmes ? Faites-le nous savoir.

Étapes suivantes

Dans ce guide, vous avez appris à gérer les problèmes courants. Vous avez également découvert d’autres méthodes de dépannage génériques.