Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ten artykuł zawiera wskazówki dotyczące rozwiązywania niektórych typowych problemów, które mogą napotkać klienci.
Token dostępu zbyt długi
Możliwe błędy
- Po stronie klienta
ERR_CONNECTION_ - 414 Identyfikator URI jest za długi
- 413 Zbyt duży ładunek
- Token dostępu nie może być dłuższy niż 4K. 413 Jednostka żądania jest za duża
Główna przyczyna
W przypadku protokołu HTTP/2 maksymalna długość pojedynczego nagłówka wynosi 4 K, więc jeśli używasz przeglądarki do uzyskiwania dostępu do usługi platformy Azure, występuje błąd ERR_CONNECTION_ dotyczący tego ograniczenia.
W przypadku klientów HTTP/1.1 lub C# maksymalna długość identyfikatora URI wynosi 12 K, a maksymalna długość nagłówka wynosi 16 K.
W wersji SDK 1.0.6 lub nowszej, /negotiate rzuca 413 Payload Too Large gdy wygenerowany token dostępu jest większy niż 4 K.
Rozwiązanie
Domyślnie oświadczenia z context.User.Claims są uwzględniane podczas generowania tokenu dostępu JWT do usługi ASRS (Azure SignalRService), dzięki czemu oświadczenia są zachowywane i mogą być przekazywane z usługi ASRS do Hub usługi , gdy klient nawiązuje połączenie z usługą Hub.
W niektórych przypadkach context.User.Claims są używane do przechowywania wielu informacji dla serwera aplikacji, z których większość nie jest używana przez Hub, ale przez inne komponenty.
Wygenerowany token dostępu jest przekazywany przez sieć, a w przypadku połączeń Protokołu WebSocket/SSE tokeny dostępu są przekazywane przez ciągi zapytań. Najlepszym rozwiązaniem jest więc przekazanie tylko niezbędnych oświadczeń od klienta przez ASRS do serwera aplikacji, gdy jest to wymagane przez Hub.
ClaimsProvider Istnieje możliwość dostosowania oświadczeń przekazywanych do usługi ASRS wewnątrz tokenu dostępu.
W przypadku ASP.NET Core:
services.AddSignalR()
.AddAzureSignalR(options =>
{
// pick up necessary claims
options.ClaimsProvider = context => context.User.Claims.Where(...);
});
W przypadku ASP.NET:
services.MapAzureSignalR(GetType().FullName, options =>
{
// pick up necessary claims
options.ClaimsProvider = context.Authentication?.User.Claims.Where(...);
});
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Wymagany protokół TLS 1.2
Możliwe błędy
- błąd ASP.NET "Brak dostępnego serwera" #279
- ASP.NET "Połączenie nie jest aktywne, nie można wysłać danych do usługi". Błąd 324
- "Wystąpił błąd podczas wykonywania żądania HTTP do
https://<API endpoint>. Ten błąd może wystąpić, jeśli certyfikat serwera nie został prawidłowo skonfigurowany przy użyciu HTTP.SYS w przypadku protokołu HTTPS. Możliwą przyczyną tego błędu jest niezgodność powiązania zabezpieczeń między klientem a serwerem".
Główna przyczyna
Usługa platformy Azure obsługuje tylko protokół TLS1.2 w przypadku problemów z zabezpieczeniami. W przypadku platformy .NET Framework istnieje możliwość, że protokół TLS1.2 nie jest protokołem domyślnym. W związku z tym nie można pomyślnie ustanowić połączeń serwera z usługą ASRS.
Przewodnik po rozwiązywaniu problemów
Jeśli ten błąd można odtworzyć lokalnie, usuń zaznaczenie pola Wyboru Tylko mój kod i wyrzuć wszystkie wyjątki CLR i debuguj serwer aplikacji lokalnie, aby zobaczyć, jaki wyjątek zgłasza.
Usuń zaznaczenie pola wyboru Tylko mój kod
Zgłaszanie wyjątków CLR
Zobacz wyjątki zgłaszane podczas debugowania kodu po stronie serwera aplikacji:
W przypadku ASP.NET można również dodać następujący kod do elementu
Startup.cs, aby włączyć szczegółowe śledzenie i zobaczyć błędy z dziennika.app.MapAzureSignalR(this.GetType().FullName); // Make sure this switch is called after MapAzureSignalR GlobalHost.TraceManager.Switch.Level = SourceLevels.Information;
Rozwiązanie
Dodaj poniższy kod do pliku Startup.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
400 Bad Request returned for client requests (Błąd 400 — Nieprawidłowe żądanie zwracany w przypadku żądań klientów)
Główna przyczyna
Sprawdź, czy żądanie klienta ma wiele hub ciągów zapytania. Parametr hub jest zachowywany, a jeśli usługa wykryje więcej niż jeden hub w zapytaniu, zwraca błąd 400.
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Błąd 401 — nieautoryzowany, zwracany w przypadku żądań klienta
Główna przyczyna
Obecnie wartość domyślna okresu istnienia JWT wynosi jedną (1) godzinę.
W przypadku ASP.NET Core SignalR, gdy używa typu transportu WebSocket, jest to ok.
W przypadku innych typów transportu ASP.NET Core SignalR, takich jak SSE i długie odpytywanie, domyślnie połączenie może trwać najwyżej przez jedną godzinę.
W przypadku usługi ASP.NET SignalR klient wysyła /ping żądanie 'utrzymaj aktywność' do serwisu od czasu do czasu, gdy /ping nie działa, klient przerywa połączenie i nigdy nie łączy się ponownie. W przypadku ASP.NET SignalR domyślny okres istnienia tokenu powoduje, że połączenie trwa przez co najwyżej godzinę dla całego typu transportu.
Rozwiązanie
W przypadku problemów z zabezpieczeniami rozszerzenie czasu wygaśnięcia nie jest zachęcane. Zalecamy dodanie logiki ponownego połączenia od klienta, aby wznowić połączenie w przypadku wystąpienia takiego błędu 401. Gdy klient ponownie uruchomi połączenie, negocjuje z serwerem aplikacji, aby ponownie pobrać JWT i uzyskać odnowiony token.
Sprawdź tutaj , jak ponownie uruchomić połączenia klienckie.
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Błąd 404 zwracany w przypadku żądań klientów
W przypadku trwałego połączenia usługi SignalR najpierw /negotiate z usługą Azure SignalR, a następnie ustanawia rzeczywiste połączenie z usługą Azure SignalR.
Przewodnik po rozwiązywaniu problemów
- Poniżej przedstawiono sposób wyświetlania wychodzących żądań w celu pobrania żądania od klienta do usługi.
- Sprawdź adres URL żądania, gdy wystąpi błąd 404. Jeśli adres URL jest przeznaczony dla aplikacji internetowej i podobny do
{your_web_app}/hubs/{hubName}, sprawdź, czy klientSkipNegotiationma wartośćtrue. Klient otrzymuje adres URL przekierowania podczas pierwszego negocjowania z serwerem aplikacji. Klient nie może pominąć negocjacji podczas korzystania z usługi Azure SignalR. - Kolejne 404 może wystąpić, gdy żądanie połączenia jest obsługiwane ponad pięć (5) sekund po
/negotiatewywołaniu. Sprawdź sygnaturę czasową żądania klienta i otwórz dla nas problem, jeśli żądanie do usługi ma powolną odpowiedź.
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
404 zwrócone dla żądania ponownego połączenia usługi SignalR ASP.NET
W przypadku ASP.NET SignalR, gdy połączenie klienta spadnie, ponownie nawiąże połączenie przy użyciu tego samego connectionId przez trzy razy przed zatrzymaniem połączenia.
/reconnect To może pomóc, jeśli połączenie zostało przerwane z powodu sporadycznych problemów z siecią, które /reconnect mogą pomyślnie przywrócić stale połączenie. W innych okolicznościach, na przykład, gdy połączenie klienta jest przerywane z powodu zerwania kierowanego połączenia z serwerem, lub gdy usługa SignalR Service ma pewne wewnętrzne błędy, takie jak ponowne uruchomienie instancji, przejście w tryb failover, czy wdrożenie. Połączenie już nie istnieje, dlatego /reconnect zwraca wartość 404. Jest to oczekiwane zachowanie dla /reconnect i po trzech ponownych próbach połączenia zostanie zatrzymane. Zalecamy użycie logiki ponownego uruchomienia połączenia po zatrzymaniu połączenia.
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
429 (Zbyt wiele żądań) zwracany przy żądaniach klienta
Są dwa przypadki.
Liczba połączeń współbieżnych przekracza limit
W przypadku wystąpień bezpłatnych limit liczby połączeń współbieżnych wynosi 20. W przypadku wystąpień standardowych, limit liczby połączeń współbieżnychna jednostkę wynosi 1 tysiąc, co oznacza, że jednostka100 zezwala na 100 tysięcy połączeń współbieżnych.
Połączenia obejmują zarówno połączenia klienta, jak i serwera. Sprawdź tutaj , jak są liczone połączenia.
NieograniczonaNegocjacja
Jeśli zbyt wielu klientów negocjuje żądania w tym samym czasie, mogą zostać one ograniczone. Limit odnosi się do liczby jednostek, gdzie więcej jednostek oznacza wyższy limit. Oprócz tego zalecamy losowe opóźnienie przed ponownym nawiązaniem połączenia, sprawdź tutaj przykłady ponawiania prób.
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Błąd 500 podczas negocjowania: usługa Azure SignalR Service nie jest jeszcze połączona. Spróbuj ponownie później
Główna przyczyna
Ten błąd jest zgłaszany, gdy nie ma połączenia serwera z usługą Azure SignalR Service.
Przewodnik po rozwiązywaniu problemów
Włącz śledzenie po stronie serwera, aby dowiedzieć się szczegółów błędu podczas próby nawiązania połączenia z usługą Azure SignalR Service.
Włączanie rejestrowania po stronie serwera dla ASP.NET Core SignalR
Rejestrowanie po stronie serwera dla ASP.NET Core SignalR integruje się z ILogger rejestrowaniem opartym na platformie ASP.NET Core. Rejestrowanie po stronie serwera można włączyć przy użyciu metody ConfigureLogging, przykładowe użycie w następujący sposób:
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConsole();
logging.AddDebug();
})
Kategorie rejestratora dla usługi Azure SignalR zawsze zaczynają się od Microsoft.Azure.SignalR. Aby włączyć szczegółowe logi z usługi Azure SignalR, skonfiguruj powyższe prefiksy na poziom Debug w pliku appsettings.json, patrz następujący przykład:
{
"Logging": {
"LogLevel": {
...
"Microsoft.Azure.SignalR": "Debug",
...
}
}
}
Włącz ślady po stronie serwera dla ASP.NET SignalR
W przypadku korzystania z wersji >zestawu SDK = 1.0.0można włączyć śledzenie, dodając następujące informacje do web.config: (Szczegóły)
<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>
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Utrata połączenia klienta
Gdy klient jest połączony z usługą Azure SignalR, trwałe połączenie między klientem a usługą Azure SignalR może czasami spaść z różnych powodów. W tej sekcji opisano kilka możliwości powodujących takie upuszczanie połączenia i przedstawiono wskazówki dotyczące identyfikowania głównej przyczyny.
Możliwe błędy widoczne po stronie klienta
The remote party closed the WebSocket connection without completing the close handshakeService timeout. 30000.00ms elapsed without receiving a message from service.{"type":7,"error":"Connection closed with an error."}{"type":7,"error":"Internal server error."}
Główna przyczyna
Połączenia klienta mogą spaść w różnych okolicznościach:
- Kiedy
Hubzgłasza wyjątki z żądaniem przychodzącym - Gdy połączenie serwera, z którym klient został przekierowany, spadnie, zobacz następującą sekcję, aby uzyskać szczegółowe informacje na temat przerywania połączenia z serwerem
- Gdy występuje problem z łącznością sieciową między klientem a usługą SignalR Service
- Gdy usługa SignalR Service zawiera błędy wewnętrzne, takie jak ponowne uruchomienie wystąpienia, przejście w tryb failover, wdrożenie itd.
Przewodnik po rozwiązywaniu problemów
- Otwórz dziennik po stronie serwera aplikacji, aby sprawdzić, czy wystąpiły jakiekolwiek nietypowe zdarzenia
- Sprawdź dziennik zdarzeń po stronie serwera aplikacji, aby sprawdzić, czy serwer aplikacji został uruchomiony ponownie
- Zgłoś nam problem, podając przedział czasu, i przesyłając nam nazwę zasobu e-mailem.
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Stale zwiększa się połączenie klienta
Może to spowodować nieprawidłowe użycie połączenia klienta. Jeśli ktoś zapomni zatrzymać/usunąć klienta SignalR, połączenie pozostanie otwarte.
Możliwe błędy widoczne w metrykach usługi SignalR, które znajdują się w sekcji Monitorowanie menu zasobów witryny Azure Portal
Połączenia klientów w metrykach usługi Azure SignalR nieustannie wzrastają przez pewien czas.
Główna przyczyna
Połączenie klienta SignalR DisposeAsync nigdy nie zostanie wywołane, a połączenie pozostaje otwarte.
Przewodnik po rozwiązywaniu problemów
Sprawdź, czy klient usługi SignalR nigdy nie zamyka się.
Rozwiązanie
Sprawdź, czy zamykasz połączenie. Ręcznie wywołaj metodę HubConnection.DisposeAsync() , aby zatrzymać połączenie po jego użyciu.
Na przykład:
var connection = new HubConnectionBuilder()
.WithUrl(...)
.Build();
try
{
await connection.StartAsync();
// Do your stuff
await connection.StopAsync();
}
finally
{
await connection.DisposeAsync();
}
Typowe nieprawidłowe użycie połączenia klienta
Przykład funkcji platformy Azure
Ten problem często występuje, gdy ktoś ustanawia połączenie klienta usługi SignalR w metodzie funkcji platformy Azure zamiast tworzenia statycznej składowej w klasie funkcji. Możesz oczekiwać, że zostanie nawiązane tylko jedno połączenie klienta, ale zamiast tego liczba połączeń klienta stale wzrasta w metrykach. Wszystkie te połączenia upuszczają się dopiero po ponownym uruchomieniu usługi Azure Function lub Azure SignalR. To zachowanie występuje, ponieważ funkcja platformy Azure ustanawia jedno połączenie klienta dla każdego żądania, a jeśli nie zatrzymasz połączenia klienta w metodzie funkcji, klient utrzymuje połączenia aktywne z usługą Azure SignalR Service.
Rozwiązanie
- Pamiętaj, aby zamknąć połączenie klienta, jeśli używasz klientów SignalR w funkcji Azure lub klienta SignalR jako singletonu.
- Zamiast używać klientów SignalR w funkcji platformy Azure, można tworzyć klientów SignalR w dowolnym miejscu i korzystać z powiązań Azure Functions dla usługi Azure SignalR Service, aby negocjować połączenie klienta z usługą Azure SignalR. Można również użyć powiązania do wysyłania komunikatów. Przykłady do negocjowania klienta i wysyłania komunikatów można znaleźć tutaj. Więcej informacji można znaleźć tutaj.
- W przypadku korzystania z klientów usługi SignalR w funkcji platformy Azure może istnieć lepsza architektura dla danego scenariusza. Sprawdź, czy projektujesz odpowiednią architekturę bezserwerową. Możesz zapoznać się z aplikacjami czasu rzeczywistego za pomocą usług Azure SignalR Service i Azure Functions.
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Utrata połączenia z serwerem
Po uruchomieniu serwera aplikacji, w tle Azure SDK rozpoczyna inicjowanie połączeń zdalnego serwera do Azure SignalR. Zgodnie z opisem w temacie Internals of Azure SignalR Service (Wewnętrzne elementy usługi Azure SignalR Service) usługa Azure SignalR kieruje przychodzący ruch klientów do tych połączeń serwera. Po usunięciu połączenia z serwerem zamyka wszystkie obsługiwane przez niego połączenia klienckie.
Ponieważ połączenia między serwerem aplikacji i usługą SignalR Service są trwałymi połączeniami, mogą wystąpić problemy z łącznością sieciową. W zestawie SDK serwera mamy strategię Zawsze ponownie nawiązuj, aby utrzymać połączenia z serwerem. Najlepszym rozwiązaniem jest również zachęcanie użytkowników do dodawania logiki ciągłego ponownego łączenia do klientów z losowym czasem opóźnienia, aby uniknąć ogromnych równoczesnych żądań do serwera.
Regularnie pojawiają się nowe wersje usługi Azure SignalR, a czasami poprawki lub uaktualnienia na całej platformie Azure albo od czasu do czasu występują przerwy spowodowane przez nasze usługi zależne. Te zdarzenia mogą spowodować krótki okres zakłóceń w działaniu usługi, ale jeśli po stronie klienta działa mechanizm rozłączania i ponownego nawiązywania połączeń, efekt jest minimalny, podobnie jak w przypadku typowych rozłączeń i ponownych połączeń po stronie klienta.
W tej sekcji opisano kilka możliwości prowadzących do upuszczania połączenia z serwerem i przedstawiono wskazówki dotyczące identyfikowania głównej przyczyny.
Możliwe błędy widoczne po stronie serwera
[Error]Connection "..." to the service was droppedThe remote party closed the WebSocket connection without completing the close handshakeService timeout. 30000.00ms elapsed without receiving a message from service.
Główna przyczyna
Połączenie z usługą serwera zostało zakończone przez usługę ASRS (AzureSignalRService).
Wysokie użycie procesora lub głodowanie puli wątków po stronie serwera może przyczynić się do przekroczenia limitu czasu ping.
W przypadku ASP.NET SignalR znany problem został rozwiązany w zestawie SDK 1.6.0. Uaktualnij zestaw SDK do najnowszej wersji.
Wyczerpanie zasobów puli wątków
Jeśli brakuje zasobów na serwerze, oznacza to, że żadne wątki nie pracują nad przetwarzaniem komunikatów. Żaden z wątków nie odpowiada w danej metodzie.
Zwykle w metodach asynchronicznych asynchroniczność nad synchronizacją lub przy pomocy Task.Result/Task.Wait() powoduje ten scenariusz.
Zobacz najlepsze rozwiązania dotyczące wydajności ASP.NET Core.
Zobacz więcej na temat wyczerpania puli wątków.
Jak wykryć głodowanie puli wątków
Sprawdź liczbę wątków. Jeśli w tym czasie nie ma żadnych skoków, wykonaj następujące kroki:
Jeśli używasz Azure App Service, sprawdź liczbę wątków w metrykach. Sprawdź agregację
Max:
Jeśli używasz środowiska .NET Framework, możesz znaleźć metryki w monitorze wydajności na serwerowej maszynie wirtualnej.
Jeśli używasz platformy .NET Core w kontenerze, zobacz Zbieranie diagnostyki w kontenerach.
Możesz również użyć kodu do wykrywania przeciążenia puli wątków.
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!");
}
}
}
Dodaj ją do usługi:
service.AddSingleton<ThreadPoolStarvationDetector>();
Następnie sprawdź dziennik po rozłączeniu serwera z powodu przekroczenia limitu czasu ping.
Jak znaleźć główną przyczynę głodu puli wątków
Aby znaleźć główną przyczynę wyczerpania puli wątków:
- Zrzuć pamięć, a następnie przeanalizuj stos wywołań. Aby uzyskać więcej informacji, zobacz Zbieranie i analizowanie zrzutów pamięci.
- Użyj clrmd, aby zrzucić pamięć po wykryciu przestoju w puli wątków. Następnie zarejestruj stos wywołań.
Przewodnik po rozwiązywaniu problemów
- Otwórz dziennik po stronie serwera aplikacji, aby sprawdzić, czy wystąpiły jakiekolwiek nietypowe zdarzenia.
- Sprawdź dziennik zdarzeń po stronie serwera aplikacji, aby sprawdzić, czy serwer aplikacji został uruchomiony ponownie.
- Utwórz zgłoszenie. Podaj przedział czasu i wyślij do nas wiadomość e-mail z nazwą zasobu.
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Wskazówki
Jak wyświetlić żądanie wychodzące od klienta?
Weź ASP.NET Core na przykład (ASP.NET jeden jest podobny):
W przeglądarce: Weźmy Chrom jako przykład, możesz użyć F12, aby otworzyć okno konsoli, a następnie przełączyć się na kartę Sieć. Może być konieczne odświeżenie strony przy użyciu F5 w celu przechwycenia sieci od samego początku.
Z poziomu klienta języka C#:
Lokalne ruchy internetowe można wyświetlać przy użyciu programu Fiddler. Ruch protokołu WebSocket jest obsługiwany od wersji Fiddler 4.5.
Jak ponownie uruchomić połączenie klienta?
Oto przykładowe kody zawierające logikę ponownego uruchamiania połączenia ze strategią ALWAYS RETRY:
Masz problemy lub opinie dotyczące rozwiązywania problemów? Daj nam znać.
Następne kroki
W tym przewodniku przedstawiono sposób obsługi typowych problemów. Możesz również dowiedzieć się więcej ogólnych metod rozwiązywania problemów.