Guida alla risoluzione dei problemi per Servizio Azure SignalR problemi comuni

Questo articolo fornisce indicazioni sulla risoluzione dei problemi per alcuni dei problemi comuni che i clienti potrebbero riscontrare.

Token di accesso troppo lungo

Possibili errori

  • Lato client ERR_CONNECTION_
  • 414 - URI richiesta troppo lungo
  • 413 Payload Too Large
  • Il token di accesso non deve superare i 4K. 413 Entità della richiesta troppo grande

Causa principale

Per HTTP/2, la lunghezza massima per una singola intestazione è 4 K, quindi se si usa il browser per accedere al servizio di Azure, si verificherà un errore ERR_CONNECTION_ per questa limitazione.

Per i client HTTP/1.1 o C#, la lunghezza massima dell'URI è 12 K, la lunghezza massima dell'intestazione è 16 K.

Con SDK versione 1.0.6 o successiva, /negotiate genererà 413 Payload Too Large quando il token di accesso generato è maggiore di 4 K.

Soluzione

Per impostazione predefinita, le attestazioni da context.User.Claims vengono incluse durante la generazione di token di accesso JWT ad ASRS (Azure SignalRService), in modo che le attestazioni vengano mantenute e possano essere passate da ASRS a quando Hub il client si connette a Hub.

In alcuni casi, context.User.Claims vengono usati per archiviare molte informazioni per il server app, la maggior parte delle quali non vengono usate da Hubs ma da altri componenti.

Il token di accesso generato viene passato attraverso la rete e per le connessioni WebSocket/S edizione Standard i token di accesso vengono passati tramite stringhe di query. Pertanto, come procedura consigliata, è consigliabile passare solo le attestazioni necessarie dal client tramite ASRS al server app quando l'hub necessita.

ClaimsProvider È possibile personalizzare le attestazioni che passano all'asrs all'interno del token di accesso.

Per ASP.NET Core:

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

Per ASP.NET:

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

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

TLS 1.2 obbligatorio

Possibili errori

  • ASP.NET errore "Nessun server disponibile" #279
  • ASP.NET "La connessione non è attiva, i dati non possono essere inviati al servizio". Errore 324
  • "Si è verificato un errore durante l'esecuzione della richiesta HTTP a https://<API endpoint>. Questo errore potrebbe essere dovuto al fatto che il certificato del server non è configurato correttamente con HTTP.SYS nel caso HTTPS. Questo errore potrebbe anche essere causato da una mancata corrispondenza dell'associazione di sicurezza tra il client e il server."

Causa principale

Il servizio di Azure supporta solo TLS1.2 per problemi di sicurezza. Con .NET Framework, è possibile che TLS1.2 non sia il protocollo predefinito. Di conseguenza, le connessioni server ad ASRS non possono essere stabilite correttamente.

Guida alla risoluzione dei problemi

  1. Se questo errore può essere riprodotto localmente, deselezionare Just My Code e generare tutte le eccezioni CLR ed eseguire il debug del server app in locale per visualizzare le eccezioni generate.

    • Deselezionare Just My Code

      Uncheck Just My Code

    • Generare eccezioni CLR

      Throw CLR exceptions

    • Vedere le eccezioni generate durante il debug del codice sul lato server dell'app:

      Exception throws

  2. Per ASP.NET, è anche possibile aggiungere il codice seguente all'utente Startup.cs per abilitare la traccia dettagliata e visualizzare gli errori del log.

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

Soluzione

Aggiungere il codice seguente all'avvio:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

Errore 400 Richiesta non valida restituito per le richieste del client

Causa principale

Controllare se la richiesta client include più hub stringhe di query. hub è un parametro di query mantenuto e 400 genererà se il servizio rileva più di uno hub nella query.

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

401 - Non autorizzata restituito per le richieste client

Causa principale

Attualmente il valore predefinito della durata del token JWT è un'ora (1).

Per ASP.NET Core SignalR, quando usa il tipo di trasporto WebSocket, è OK.

Per ASP.NET altro tipo di trasporto core SignalR, S edizione Standard e long-polling, la durata predefinita significa che per impostazione predefinita la connessione può essere mantenuta al massimo per un'ora.

Per ASP.NET SignalR, il client invia una /ping richiesta "keep alive" al servizio di volta in volta, quando ha /ping esito negativo, il client interrompe la connessione e non si riconnette mai. Per ASP.NET SignalR, la durata del token predefinita dura al massimo un'ora per tutto il tipo di trasporto.

Soluzione

Per i problemi di sicurezza, l'estensione della durata (TTL) non è consigliata. È consigliabile aggiungere la logica di riconnessione dal client per riavviare la connessione quando si verifica tale 401. Quando il client riavvia la connessione, negozierà con il server app per ottenere nuovamente il token JWT e ottenere un token rinnovato.

Vedere qui per informazioni su come riavviare le connessioni client.

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

404 restituito per le richieste client

Per una connessione permanente di SignalR, prima /negotiate al servizio Azure SignalR e quindi stabilisce la connessione reale al servizio Azure SignalR.

Guida alla risoluzione dei problemi

  • Di seguito Come visualizzare le richieste in uscita per ottenere la richiesta dal client al servizio.
  • Controllare l'URL della richiesta quando si verifica la versione 404. Se l'URL è destinato all'app Web e simile a {your_web_app}/hubs/{hubName}, verificare se il client SkipNegotiation è true. Il client riceve un URL di reindirizzamento quando negozia per la prima volta con il server app. Il client non deve ignorare la negoziazione quando si usa Azure SignalR.
  • Un altro 404 può verificarsi quando la richiesta di connessione viene gestita più di cinque (5) secondi dopo /negotiate la chiamata. Controllare il timestamp della richiesta client e aprire un problema se la richiesta al servizio ha una risposta lenta.

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

404 restituito per la richiesta di riconnessione di ASP.NET SignalR

Per ASP.NET SignalR, quando la connessione client viene interrotta, si riconnette usando lo stesso per connectionId tre volte prima di arrestare la connessione. /reconnect può essere utile se la connessione viene eliminata a causa di problemi intermittenti di rete che /reconnect possono ristabilire correttamente la connessione persistente. In altre circostanze, ad esempio, la connessione client viene eliminata a causa dell'eliminazione della connessione al server indirizzato oppure Servizio SignalR presenta alcuni errori interni, ad esempio riavvio/failover/distribuzione dell'istanza, la connessione non esiste più, quindi /reconnect restituisce 404. Si tratta del comportamento previsto per /reconnect e dopo tre tentativi di ripetizione della connessione. Quando la connessione si arresta, è consigliabile avere la logica di riavvio della connessione.

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

429 (Troppe richieste) restituite per le richieste client

I casi possibili sono due:

Il numero di connessioni simultanee supera il limite

Per le istanze gratuite, il limite di conteggio delle connessioni simultanee è 20 Per le istanze Standard, il limite di conteggio delle connessioni simultanee per unità è 1 K, il che significa che Unit100 consente connessioni simultanee da 100 K.

Le connessioni includono connessioni client e server. Controllare qui la modalità di conteggio delle connessioni.

Troppe richieste negoziate contemporaneamente

È consigliabile avere un ritardo casuale prima della riconnessione, verificare qui la presenza di esempi di ripetizione dei tentativi.

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

500 Errore durante la negoziazione: Servizio Azure SignalR non è ancora connesso, riprovare più tardi

Causa principale

Questo errore viene segnalato quando non è presente alcuna connessione server a Servizio Azure SignalR connessa.

Guida alla risoluzione dei problemi

Abilitare la traccia lato server per individuare i dettagli dell'errore quando il server tenta di connettersi a Servizio Azure SignalR.

Abilitare la registrazione lato server per ASP.NET Core SignalR

La registrazione lato server per ASP.NET Core SignalR si integra con la ILogger registrazione basata fornita nel framework ASP.NET Core. È possibile abilitare la registrazione lato server usando ConfigureLogging, un utilizzo di esempio come indicato di seguito:

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

Le categorie di logger per Azure SignalR iniziano sempre con Microsoft.Azure.SignalR. Per abilitare i log dettagliati da Azure SignalR, configurare i prefissi precedenti per il Debug livello nel file appsettings.json , come illustrato di seguito:

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

Abilitare le tracce lato server per ASP.NET SignalR

Quando si usa la versione >dell'SDK = 1.0.0, è possibile abilitare le tracce aggiungendo quanto segue a web.config: (Dettagli)

<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>

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

Eliminazione della connessione client

Quando il client è connesso ad Azure SignalR, la connessione permanente tra il client e Azure SignalR può talvolta cadere per motivi diversi. Questa sezione descrive diverse possibilità che causano l'eliminazione di tali connessioni e fornisce alcune indicazioni su come identificare la causa radice.

Possibili errori rilevati dal lato 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."}

Causa principale

Le connessioni client possono cadere in varie circostanze:

  • Quando Hub genera eccezioni con la richiesta in ingresso
  • Quando la connessione al server a cui il client è stato indirizzato, viene eliminata, vedere la sezione seguente per informazioni dettagliate sulle interruzioni della connessione al server
  • Quando si verifica un problema di connettività di rete tra client e Servizio SignalR
  • Quando Servizio SignalR presenta alcuni errori interni, ad esempio il riavvio dell'istanza, il failover, la distribuzione e così via

Guida alla risoluzione dei problemi

  1. Aprire il log sul lato server dell'app per verificare se si è verificato un evento anomalo
  2. Controllare il registro eventi sul lato server dell'app per verificare se il server app è stato riavviato
  3. Creare un problema per fornire l'intervallo di tempo e inviare un messaggio di posta elettronica al nome della risorsa

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

La connessione client aumenta costantemente

Potrebbe essere causato da un utilizzo improprio della connessione client. Se qualcuno dimentica di arrestare/eliminare il client SignalR, la connessione rimane aperta.

Possibili errori rilevati dalle metriche di SignalR nella sezione Monitoraggio del menu delle risorse portale di Azure

Le connessioni client aumentano costantemente per molto tempo nelle metriche di Azure SignalR.

Client connection increasing constantly

Causa principale

La connessione client SignalR non viene DisposeAsync mai chiamata, la connessione rimane aperta.

Guida alla risoluzione dei problemi

Controllare se il client SignalR non viene mai chiuso.

Soluzione

Controllare se si chiude la connessione. Chiamare HubConnection.DisposeAsync() manualmente per arrestare la connessione dopo averlo usato.

Ad esempio:

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

Utilizzo comune della connessione client non corretta

Esempio di funzione di Azure

Questo problema si verifica spesso quando un utente stabilisce una connessione client SignalR in un metodo funzione di Azure anziché renderlo un membro statico nella classe di funzione. Ci si potrebbe aspettare che venga stabilita una sola connessione client, ma si noterà che il numero di connessioni client aumenta costantemente nelle metriche. Tutte queste connessioni vengono cancellate solo dopo il riavvio del servizio Funzioni di Azure o azure SignalR. Questo comportamento è dovuto al fatto che per ogni richiesta, Funzione di Azure crea una connessione client e, se non si arresta la connessione client nel metodo di funzione, il client mantiene attive le connessioni al servizio Azure SignalR.

Soluzione

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

Eliminazione della connessione al server

All'avvio del server app, in background, Azure SDK inizia ad avviare le connessioni server ad Azure SignalR remoto. Come descritto in Internals of Servizio Azure SignalR, Azure SignalR instrada i traffico client in ingresso a queste connessioni server. Una volta eliminata una connessione server, verranno chiuse anche tutte le connessioni client gestite.

Poiché le connessioni tra il server app e Servizio SignalR sono connessioni persistenti, potrebbero verificarsi problemi di connettività di rete. In Server SDK è disponibile una strategia di riconnessione sempre alle connessioni server. Come procedura consigliata, si consiglia anche agli utenti di aggiungere logica di riconnessione continua ai client con un ritardo casuale per evitare richieste simultanee massicce al server.

Regolarmente, sono disponibili nuove versioni per il Servizio Azure SignalR e talvolta l'applicazione di patch o gli aggiornamenti a livello di Azure o occasionalmente interruzioni dai servizi dipendenti. Questi eventi possono causare un breve periodo di interruzione del servizio, ma purché il lato client abbia un meccanismo di disconnessione/riconnessione, l'effetto è minimo come qualsiasi disconnessione sul lato client causato dalla riconnessione.

In questa sezione vengono descritte diverse possibilità che causano l'eliminazione della connessione al server e vengono fornite indicazioni su come identificare la causa radice.

Possibili errori rilevati dal lato server

  • [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.

Causa principale

La connessione al servizio server viene chiusa dall'ASRS (Azure SignalRService).

Per il timeout del ping, potrebbe essere causato da un utilizzo elevato della CPU o dalla fame del pool di thread sul lato server.

Per ASP.NET SignalR, è stato risolto un problema noto in SDK 1.6.0. Aggiornare l'SDK alla versione più recente.

Fame del pool di thread

Se il server sta cercando di fame, significa che nessun thread sta lavorando all'elaborazione dei messaggi. Tutti i thread non rispondono in un determinato metodo.

In genere, questo scenario è causato dalla sincronizzazione asincrona o da Task.Result/Task.Wait() nei metodi asincroni.

Vedere ASP.NET Procedure consigliate per le prestazioni principali.

Vedere altre informazioni sulla fame del pool di thread.

Come rilevare la fame del pool di thread

Controllare il numero di thread. Se non sono presenti picchi in quel momento, seguire questa procedura:

  • Se si usa app Azure Servizio, controllare il numero di thread nelle metriche. Controllare l'aggregazione Max :

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

  • Se si usa .NET Framework, è possibile trovare le metriche nel monitoraggio delle prestazioni nella macchina virtuale del server.

  • Se si usa .NET Core in un contenitore, vedere Raccogliere la diagnostica nei contenitori.

È anche possibile usare il codice per rilevare la fame del pool di thread:

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!");
        }
    }
}

Aggiungerlo al servizio:

service.AddSingleton<ThreadPoolStarvationDetector>();

Controllare quindi il log quando la connessione al server è disconnessa dal timeout ping.

Come trovare la causa radice della fame del pool di thread

Per trovare la causa radice della fame del pool di thread:

  • Eseguire il dump della memoria e quindi analizzare lo stack di chiamate. Per altre informazioni, vedere Raccogliere e analizzare i dump della memoria.
  • Usare clrmd per eseguire il dump della memoria quando viene rilevata la fame del pool di thread. Registrare quindi lo stack di chiamate.

Guida alla risoluzione dei problemi

  1. Aprire il log sul lato server dell'app per verificare se si è verificato un evento anomalo.
  2. Controllare il registro eventi sul lato server dell'app per verificare se il server app è stato riavviato.
  3. Creare un problema. Specificare l'intervallo di tempo e inviare un messaggio di posta elettronica al nome della risorsa.

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

Suggerimenti

Come visualizzare la richiesta in uscita dal client?

Prendere ASP.NET Core 1, ad esempio (ASP.NET uno è simile):

  • Dal browser: prendere Chrome come esempio, è possibile usare F12 per aprire la finestra della console e passare alla scheda Rete . Potrebbe essere necessario aggiornare la pagina usando F5 per acquisire la rete fin dall'inizio.

    Chrome View Network

  • Dal client C#:

    È possibile visualizzare il traffico Web locale usando Fiddler. I traffico WebSocket sono supportati a partire da Fiddler 4.5.

    Fiddler View Network

Come riavviare la connessione client?

Ecco i codici di esempio contenenti la logica di connessione di riavvio con la strategia ALWAYS RETRY:

Problemi o commenti sulla risoluzione dei problemi? Segnalarli.

Passaggi successivi

In questa guida si è appreso come gestire i problemi comuni. È anche possibile ottenere altre informazioni sui metodi di risoluzione dei problemi generici.