Felsökningsguide för vanliga problem med Azure SignalR Service
Den här artikeln innehåller felsökningsvägledning för några av de vanliga problem som kunder kan stöta på.
Åtkomsttoken är för lång
Möjliga fel
- Klientsidan
ERR_CONNECTION_
- 414 URI för lång
- 413 nyttolast är för stor
- Åtkomsttoken får inte vara längre än 4 000. 413 Begärandeentiteten är för stor
Rotorsak
För HTTP/2 är maxlängden för en enda rubrik 4 K, så om du använder webbläsaren för att komma åt Azure-tjänsten uppstår ett fel ERR_CONNECTION_
för den här begränsningen.
För HTTP/1.1- eller C#-klienter är den maximala URI-längden 12 K och den maximala sidhuvudlängden är 16 K.
Med SDK version 1.0.6 eller senare /negotiate
genererar 413 Payload Too Large
när den genererade åtkomsttoken är större än 4 K.
Lösning
Som standard inkluderas anspråk från context.User.Claims
när JWT-åtkomsttoken genereras till ASRS(Azure SignalR Service), så att anspråken bevaras och kan skickas från ASRS till Hub
när klienten ansluter till Hub
.
I vissa fall context.User.Claims
används för att lagra mycket information för appservern, varav de flesta inte används av Hub
s utan av andra komponenter.
Den genererade åtkomsttoken skickas via nätverket och för WebSocket/SSE-anslutningar skickas åtkomsttoken via frågesträngar. Vi rekommenderar därför att du bara skickar nödvändiga anspråk från klienten via ASRS till din appserver när hubben behöver det.
Du kan anpassa anspråken som skickas ClaimsProvider
till ASRS i åtkomsttoken.
För ASP.NET Core:
services.AddSignalR()
.AddAzureSignalR(options =>
{
// pick up necessary claims
options.ClaimsProvider = context => context.User.Claims.Where(...);
});
För ASP.NET:
services.MapAzureSignalR(GetType().FullName, options =>
{
// pick up necessary claims
options.ClaimsProvider = context.Authentication?.User.Claims.Where(...);
});
Har du problem eller feedback om felsökningen? Berätta för oss.
TLS 1.2 krävs
Möjliga fel
- ASP.NET felet "Ingen tillgänglig server" #279
- ASP.NET "Anslutningen är inte aktiv, data kan inte skickas till tjänsten." fel #324
- "Ett fel uppstod när HTTP-begäran skulle skickas till
https://<API endpoint>
. Det här felet kan inträffa om servercertifikatet inte är korrekt konfigurerat med HTTP.SYS i HTTPS-fallet. Den möjliga orsaken till det här felet är ett matchningsfel för säkerhetsbindningen mellan klienten och servern."
Rotorsak
Azure Service stöder endast TLS1.2 för säkerhetsproblem. Med .NET Framework är det möjligt att TLS1.2 inte är standardprotokollet. Det innebär att serveranslutningarna till ASRS inte kan upprättas.
Felsökningsguide
Om det här felet kan återskapas lokalt avmarkerar du Bara min kod och utlöser alla CLR-undantag och felsöker appservern lokalt för att se vilket undantag som utlöse.
Avmarkera Bara min kod
Generera CLR-undantag
Se undantagen när du felsöker koden på appserversidan:
För ASP.NET kan du också lägga till följande kod i din
Startup.cs
för att aktivera detaljerad spårning och se felen från loggen.app.MapAzureSignalR(this.GetType().FullName); // Make sure this switch is called after MapAzureSignalR GlobalHost.TraceManager.Switch.Level = SourceLevels.Information;
Lösning
Lägg till följande kod i din start:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Har du problem eller feedback om felsökningen? Berätta för oss.
400 Felaktig begäran returneras för klientförfrågningar
Rotorsak
Kontrollera om klientbegäran har flera hub
frågesträngar. hub
Är bevarad frågeparameter och om tjänsten identifierar fler än en hub
i frågan returneras ett 400-fel.
Har du problem eller feedback om felsökningen? Berätta för oss.
401 Behörighet saknas returneras för klientbegäran
Rotorsak
För närvarande är standardvärdet för JWT-tokens livslängd en (1) timme.
För ASP.NET Core SignalR är det ok när den använder WebSocket-transporttypen.
För ASP.NET Core SignalR:s andra transporttyp, SSE och long-polling, innebär standardlivslängden att anslutningen som mest kan finnas kvar i en timme.
För ASP.NET SignalR skickar klienten en /ping
"keep alive"-begäran till tjänsten då och då, när felet /ping
misslyckas, avbryter klienten anslutningen och återansluter aldrig. För ASP.NET SignalR gör standardtokens livslängd att anslutningen varar högst en timme för all transporttyp.
Lösning
När det gäller säkerhetsproblem rekommenderar vi inte att TTL utökas. Vi föreslår att du lägger till återanslutningslogik från klienten för att starta om anslutningen när sådan 401 inträffar. När klienten startar om anslutningen förhandlas den med appservern för att hämta JWT-token igen och hämta en förnyad token.
Här hittar du information om hur du startar om klientanslutningar.
Har du problem eller feedback om felsökningen? Berätta för oss.
404 returneras för klientbegäran
För en beständig SignalR-anslutning upprättas den först /negotiate
till Azure SignalR-tjänsten och upprättar sedan den verkliga anslutningen till Azure SignalR-tjänsten.
Felsökningsguide
- Följ Så här visar du utgående begäranden för att hämta begäran från klienten till tjänsten.
- Kontrollera URL:en för begäran när 404 inträffar. Om URL:en riktar sig till webbappen och liknar
{your_web_app}/hubs/{hubName}
kontrollerar du om klientenSkipNegotiation
ärtrue
. Klienten får en omdirigerings-URL när den först förhandlar med appservern. Klienten får inte hoppa över förhandling när du använder Azure SignalR. - Ytterligare 404 kan inträffa när anslutningsbegäran hanteras mer än fem (5) sekunder efter
/negotiate
att den anropats. Kontrollera tidsstämpeln för klientbegäran och öppna ett problem för oss om begäran till tjänsten har ett långsamt svar.
Har du problem eller feedback om felsökningen? Berätta för oss.
404 returneras för ASP.NET SignalR:s återanslutningsbegäran
När klientanslutningen avbryts för ASP.NET SignalR återansluts den med samma connectionId
i tre gånger innan anslutningen stoppas. /reconnect
kan hjälpa om anslutningen avbryts på grund av tillfälliga problem i nätverket som /reconnect
kan återupprätta den beständiga anslutningen. Under andra omständigheter tas till exempel klientanslutningen bort på grund av att den dirigerade serveranslutningen tas bort, eller så har SignalR Service vissa interna fel som omstart av instans/redundans/distribution. Anslutningen finns inte längre, vilket /reconnect
returnerar 404
. Det är det förväntade beteendet för /reconnect
och efter tre gånger återförsök av anslutningsstoppen. Vi rekommenderar att du har logik för omstart av anslutningen när anslutningen stoppas.
Har du problem eller feedback om felsökningen? Berätta för oss.
429 (för många begäranden) som returneras för klientbegäranden
Det finns två fall.
Antalet samtidiga anslutningar överskrider gränsen
För kostnadsfria instanser är gränsen för antal samtidiga anslutningar 20 För standardinstanser är gränsen för antal samtidiga anslutningar per enhet 1 K, vilket innebär att Unit100 tillåter 100 K samtidiga anslutningar.
Anslutningarna omfattar både klient- och serveranslutningar. Kontrollera här hur anslutningar räknas.
NegotiateThrottled
När det finns för många klienter som förhandlar om begäranden samtidigt kan det bli begränsat. Gränsen relaterar till antalet enheter som fler enheter har en högre gräns. Dessutom föreslår vi att du har en slumpmässig fördröjning innan du återansluter. Kontrollera här om det finns exempel på nya försök.
Har du problem eller feedback om felsökningen? Berätta för oss.
500 Fel vid förhandling: Azure SignalR Service är inte ansluten än. Försök igen senare
Rotorsak
Det här felet rapporteras när det inte finns någon serveranslutning till Azure SignalR Service ansluten.
Felsökningsguide
Aktivera spårning på serversidan för att ta reda på felinformationen när servern försöker ansluta till Azure SignalR Service.
Aktivera loggning på serversidan för ASP.NET Core SignalR
Loggning på serversidan för ASP.NET Core SignalR integreras med den ILogger
baserade loggning som tillhandahålls i ASP.NET Core-ramverket. Du kan aktivera loggning på serversidan med hjälp ConfigureLogging
av , en exempelanvändning på följande sätt:
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConsole();
logging.AddDebug();
})
Loggningskategorier för Azure SignalR börjar alltid med Microsoft.Azure.SignalR
. Om du vill aktivera detaljerade loggar från Azure SignalR konfigurerar du de föregående prefixen till Debug
nivå i din appsettings.json-fil i följande exempel:
{
"Logging": {
"LogLevel": {
...
"Microsoft.Azure.SignalR": "Debug",
...
}
}
}
Aktivera spårning på serversidan för ASP.NET SignalR
När du använder SDK-versionen >= 1.0.0
kan du aktivera spårningar genom att lägga till följande i web.config
: (Information)
<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>
Har du problem eller feedback om felsökningen? Berätta för oss.
Klientanslutningen avbryts
När klienten är ansluten till Azure SignalR kan den beständiga anslutningen mellan klienten och Azure SignalR ibland minska av olika skäl. Det här avsnittet beskriver flera möjligheter som orsakar en sådan anslutningsavsläppning och ger vägledning om hur du identifierar rotorsaken.
Möjliga fel som visas från klientsidan
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."}
Rotorsak
Klientanslutningar kan minskas under olika omständigheter:
- När
Hub
utlöser undantag med den inkommande begäran - När serveranslutningen, som klienten dirigerade till, avbryts läser du följande avsnitt för information om att serveranslutningen avbryts
- När ett problem med nätverksanslutningen inträffar mellan klienten och SignalR Service
- När SignalR Service har några interna fel som omstart av instans, redundans, distribution och så vidare
Felsökningsguide
- Öppna apploggen på serversidan för att se om något onormalt har inträffat
- Kontrollera händelseloggen på appserversidan för att se om appservern startades om
- Skapa ett problem för oss som anger tidsramen och skicka resursnamnet via e-post till oss
Har du problem eller feedback om felsökningen? Berätta för oss.
Klientanslutningen ökar ständigt
Felaktig användning av klientanslutningen kan orsaka det. Om någon glömmer att stoppa/ta bort SignalR-klienten förblir anslutningen öppen.
Möjliga fel som visas från SignalR:s mått som finns i avsnittet Övervakning i Resursmenyn i Azure-portalen
Klientanslutningarna ökar ständigt under lång tid i Azure SignalR:s mått.
Rotorsak
SignalR-klientanslutningen anropas DisposeAsync
aldrig och anslutningen hålls öppen.
Felsökningsguide
Kontrollera om SignalR-klienten aldrig stängs.
Lösning
Kontrollera om du stänger anslutningen. Anropa HubConnection.DisposeAsync()
manuellt för att stoppa anslutningen när du har använt den.
Till exempel:
var connection = new HubConnectionBuilder()
.WithUrl(...)
.Build();
try
{
await connection.StartAsync();
// Do your stuff
await connection.StopAsync();
}
finally
{
await connection.DisposeAsync();
}
Vanlig felaktig användning av klientanslutning
Exempel på Azure-funktion
Det här problemet uppstår ofta när någon upprättar en SignalR-klientanslutning i en Azure Function-metod i stället för att göra den till en statisk medlem i funktionsklassen. Du kanske bara förväntar dig att en klientanslutning upprättas, men i stället ser du att antalet klientanslutningar ökar kontinuerligt i mått. Alla dessa anslutningar släpps endast efter att Azure-funktionen eller Azure SignalR-tjänsten har startats om. Det här beteendet beror på att Azure Function upprättar en klientanslutning för varje begäran och om du inte stoppar klientanslutningen i funktionsmetoden håller klienten anslutningarna vid liv till Azure SignalR-tjänsten.
Lösning
- Kom ihåg att stänga klientanslutningen om du använder SignalR-klienter i Azure-funktionen eller använder SignalR-klienten som en singleton.
- I stället för att använda SignalR-klienter i Azure-funktionen kan du skapa SignalR-klienter någon annanstans och använda Azure Functions-bindningar för Azure SignalR Service för att förhandla om klienten till Azure SignalR. Och du kan också använda bindningen för att skicka meddelanden. Exempel för att förhandla om klienten och skicka meddelanden finns här. Mer information finns här.
- När du använder SignalR-klienter i Azure-funktionen kan det finnas en bättre arkitektur i ditt scenario. Kontrollera om du utformar en korrekt serverlös arkitektur. Du kan referera till serverlösa program i realtid med SignalR Service-bindningar i Azure Functions.
Har du problem eller feedback om felsökningen? Berätta för oss.
Serveranslutningen avbryts
När appservern startar, i bakgrunden, börjar Azure SDK initiera serveranslutningar till den fjärranslutna Azure SignalR. Enligt beskrivningen i Internals of Azure SignalR Service dirigerar Azure SignalR inkommande klienttrafik till dessa serveranslutningar. När en serveranslutning tas bort stänger den alla klientanslutningar som den betjänade.
Eftersom anslutningarna mellan appservern och SignalR Service är beständiga anslutningar kan det uppstå problem med nätverksanslutningen. I Server SDK har vi en Always Reconnect-strategi till serveranslutningar. Vi rekommenderar också att användarna lägger till logik för kontinuerlig återanslutning till klienterna med en slumpmässig fördröjningstid för att undvika massiva samtidiga begäranden till servern.
Det finns regelbundet nya versionsutgåvor för Azure SignalR Service, och ibland azure-omfattande korrigeringar eller uppgraderingar eller ibland avbrott från våra beroende tjänster. Dessa händelser kan medföra en kort period av avbrott i tjänsten, men så länge klientsidan har en mekanism för frånkoppling/återanslutning är effekten minimal som alla klientsidan orsakade frånkopplingsåteranslutning.
Det här avsnittet beskriver flera möjligheter som leder till att serveranslutningen avbryts och ger vägledning om hur du identifierar rotorsaken.
Möjliga fel som visas på serversidan
[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.
Rotorsak
Anslutningen till servertjänsten stängs av ASRS(Azure SignalR Service).
Hög CPU-användning eller utsvulten trådpool på serversidan kan orsaka en ping-timeout.
För ASP.NET SignalR har ett känt problem åtgärdats i SDK 1.6.0. Uppgradera din SDK till den senaste versionen.
Utsvulten trådpool
Om servern svälter innebär det att inga trådar arbetar med meddelandebearbetning. Alla trådar svarar inte i en viss metod.
Normalt, i asynkrona metoder, asynkronisering över synkronisering eller av Task.Result
/Task.Wait()
orsakar det här scenariot.
Se bästa praxis för ASP.NET Core-prestanda.
Läs mer om utsvulten trådpool.
Så här identifierar du utsvulten trådpool
Kontrollera antalet trådar. Om det inte finns några toppar vid den tidpunkten gör du följande:
Om du använder Azure App Service kontrollerar du antalet trådar i mått.
Max
Kontrollera aggregeringen:Om du använder .NET Framework kan du hitta mått i prestandaövervakaren på den virtuella serverdatorn.
Om du använder .NET Core i en container kan du läsa Samla in diagnostik i containrar.
Du kan också använda kod för att identifiera utsvulten trådpool:
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!");
}
}
}
Lägg till den i din tjänst:
service.AddSingleton<ThreadPoolStarvationDetector>();
Kontrollera sedan loggen när servern kopplades från på grund av tidsgränsen för ping.
Så här hittar du rotorsaken till utsvulten trådpool
Så här hittar du rotorsaken till utsvulten trådpool:
- Dumpa minnet och analysera sedan anropsstacken. Mer information finns i Samla in och analysera minnesdumpar.
- Använd clrmd för att dumpa minnet när utsvulten trådpool identifieras. Logga sedan anropsstacken.
Felsökningsguide
- Öppna loggen på appserversidan för att se om något onormalt har inträffat.
- Kontrollera händelseloggen på appserversidan för att se om appservern startades om.
- Skapa ett problem. Ange tidsramen och skicka resursnamnet via e-post till oss.
Har du problem eller feedback om felsökningen? Berätta för oss.
Tips
Så här visar du den utgående begäran från klienten?
Ta ASP.NET Core ett till exempel (ASP.NET en är liknande):
Från webbläsare: Ta Chrome som exempel kan du använda F12 för att öppna konsolfönstret och växla till fliken Nätverk . Du kan behöva uppdatera sidan med hjälp av F5 för att avbilda nätverket redan från början.
Från C#-klienten:
Du kan visa lokal webbtrafik med Fiddler. WebSocket-trafik stöds sedan Fiddler 4.5.
Hur startar jag om klientanslutningen?
Här är exempelkoderna som innehåller omstart av anslutningslogik med ALWAYS RETRY-strategi:
Har du problem eller feedback om felsökningen? Berätta för oss.
Nästa steg
I den här guiden har du lärt dig hur du hanterar vanliga problem. Du kan också lära dig mer allmänna felsökningsmetoder.