Objaśnienie i obsługa zdarzeń okresu istnienia połączenia w usłudze SignalR
Ostrzeżenie
Ta dokumentacja nie dotyczy najnowszej wersji usługi SignalR. Przyjrzyj się ASP.NET Core SignalR.
Ten artykuł zawiera omówienie zdarzeń połączenia usługi SignalR, ponownego nawiązywania połączenia i rozłączania, które można obsłużyć, oraz przekroczenia limitu czasu i ustawień utrzymania aktywności, które można skonfigurować.
W tym artykule założono, że masz już pewną wiedzę na temat zdarzeń usługi SignalR i okresu istnienia połączenia. Aby zapoznać się z wprowadzeniem do usługi SignalR, zobacz Wprowadzenie do usługi SignalR. Aby uzyskać listę zdarzeń okresu istnienia połączenia, zobacz następujące zasoby:
- Jak obsługiwać zdarzenia okresu istnienia połączenia w klasie Hub
- Jak obsługiwać zdarzenia okresu istnienia połączenia na klientach JavaScript
- Jak obsługiwać zdarzenia okresu istnienia połączenia na klientach platformy .NET
Wersje oprogramowania używane w tym temacie
- Visual Studio 2017
- .NET 4.5
- SignalR w wersji 2
Poprzednie wersje tego tematu
Aby uzyskać informacje na temat wcześniejszych wersji usługi SignalR, zobacz SignalR Older Versions (Starsze wersje usługi SignalR).
Pytania i komentarze
Przekaż opinię na temat tego, jak podobał Ci się ten samouczek i co możemy ulepszyć w komentarzach w dolnej części strony. Jeśli masz pytania, które nie są bezpośrednio związane z samouczkiem, możesz opublikować je na forum ASP.NET SignalR lub StackOverflow.com.
Omówienie
Ten artykuł zawiera następujące sekcje:
Linki do tematów referencyjnych interfejsu API to .NET 4.5 w wersji interfejsu API. Jeśli używasz platformy .NET 4, zobacz tematy dotyczące platformy .NET 4 interfejsu API.
Terminologia i scenariusze okresu istnienia połączenia
Procedura OnReconnected
obsługi zdarzeń w usłudze SignalR Hub może być wykonywana bezpośrednio po OnConnected
, ale nie po OnDisconnected
dla danego klienta. Przyczyną ponownego połączenia bez rozłączenia jest to, że istnieje kilka sposobów, w których słowo "połączenie" jest używane w usłudze SignalR.
Połączenia signalR, połączenia transportowe i połączenia fizyczne
W tym artykule rozróżniane są połączenia usługi SignalR, połączenia transportowe i połączenia fizyczne:
- Połączenie usługi SignalR odnosi się do relacji logicznej między klientem a adresem URL serwera obsługiwanym przez interfejs API usługi SignalR i jednoznacznie identyfikowanym przez identyfikator połączenia. Dane dotyczące tej relacji są utrzymywane przez usługę SignalR i służą do nawiązywania połączenia transportowego. Relacja kończy się, a usługa SignalR usuwa dane, gdy klient wywołuje
Stop
metodę lub osiągnięto limit czasu, gdy usługa SignalR próbuje ponownie ustanowić utracone połączenie transportowe. - Połączenie transportu odnosi się do relacji logicznej między klientem a serwerem obsługiwanym przez jeden z czterech interfejsów API transportu: WebSockets, zdarzenia wysyłane przez serwer, na zawsze ramkę lub długie sondowanie. Usługa SignalR używa interfejsu API transportu do utworzenia połączenia transportowego, a interfejs API transportu zależy od istnienia fizycznego połączenia sieciowego w celu utworzenia połączenia transportowego. Połączenie transportowe kończy się, gdy usługa SignalR zakończy połączenie lub gdy interfejs API transportu wykryje, że połączenie fizyczne zostanie przerwane.
- Połączenie fizyczne odnosi się do fizycznych łączy sieciowych — przewodów, sygnałów bezprzewodowych, routerów itp. — które ułatwiają komunikację między komputerem klienckim a komputerem serwera. Połączenie fizyczne musi być obecne w celu ustanowienia połączenia transportowego, a połączenie transportowe należy ustanowić w celu ustanowienia połączenia usługi SignalR. Jednak przerwanie połączenia fizycznego nie zawsze powoduje natychmiastowe zakończenie połączenia transportowego ani połączenia usługi SignalR, jak wyjaśniono w dalszej części tego tematu.
Na poniższym diagramie połączenie usługi SignalR jest reprezentowane przez interfejs API hubs i warstwę SignalR interfejsu API PersistentConnection, połączenie transportu jest reprezentowane przez warstwę Transports, a połączenie fizyczne jest reprezentowane przez linie między serwerem a klientami.
Podczas wywoływania Start
metody w kliencie signalR udostępniasz kod klienta usługi SignalR ze wszystkimi potrzebnymi informacjami w celu nawiązania fizycznego połączenia z serwerem. Kod klienta usługi SignalR używa tych informacji do utworzenia żądania HTTP i ustanowienia połączenia fizycznego korzystającego z jednej z czterech metod transportu. Jeśli połączenie transportowe zakończy się niepowodzeniem lub serwer ulegnie awarii, połączenie usługi SignalR nie zniknie natychmiast, ponieważ klient nadal ma informacje potrzebne do automatycznego ponownego nawiązania nowego połączenia transportowego z tym samym adresem URL usługi SignalR. W tym scenariuszu nie jest zaangażowana żadna interwencja aplikacji użytkownika, a gdy kod klienta usługi SignalR ustanawia nowe połączenie transportu, nie uruchamia nowego połączenia usługi SignalR. Ciągłość połączenia usługi SignalR jest odzwierciedlana w tym, że identyfikator połączenia, który jest tworzony podczas wywoływania Start
metody, nie zmienia się.
Procedura OnReconnected
obsługi zdarzeń w centrum jest wykonywana, gdy połączenie transportowe zostanie automatycznie nawiązane ponownie po utracie. Procedura OnDisconnected
obsługi zdarzeń jest wykonywana na końcu połączenia usługi SignalR. Połączenie usługi SignalR może kończyć się dowolnym z następujących sposobów:
- Jeśli klient wywołuje metodę
Stop
, komunikat zatrzymania jest wysyłany do serwera, a klient i serwer natychmiast zakończą połączenie usługi SignalR. - Po utracie łączności między klientem a serwerem klient próbuje ponownie nawiązać połączenie, a serwer czeka na ponowne nawiązanie połączenia z klientem. Jeśli próby ponownego nawiązania połączenia zakończą się niepowodzeniem, a okres przekroczenia limitu czasu rozłączenia zakończy się zarówno na kliencie, jak i serwerze, zakończą połączenie usługi SignalR. Klient przestaje próbować ponownie nawiązać połączenie, a serwer usuwa jego reprezentację połączenia usługi SignalR.
- Jeśli klient przestanie działać bez możliwości wywołania
Stop
metody, serwer czeka na ponowne nawiązanie połączenia z klientem, a następnie kończy połączenie usługi SignalR po upływie limitu czasu rozłączenia. - Jeśli serwer przestanie działać, klient próbuje ponownie nawiązać połączenie (ponownie utworzyć połączenie transportowe), a następnie kończy połączenie usługi SignalR po upływie limitu czasu rozłączenia.
Jeśli nie występują problemy z połączeniem, a aplikacja użytkownika kończy połączenie usługi SignalR przez wywołanie Stop
metody, połączenie usługi SignalR i połączenie transportu rozpoczynają się i kończą w mniej więcej tym samym czasie. W poniższych sekcjach opisano bardziej szczegółowo inne scenariusze.
Scenariusze rozłączania transportu
Połączenia fizyczne mogą być powolne lub mogą występować przerwy w łączności. W zależności od czynników, takich jak długość przerwy, połączenie transportowe może zostać przerwane. Usługa SignalR następnie próbuje ponownie ustanowić połączenie transportowe. Czasami interfejs API połączenia transportowego wykrywa przerwy i przerywa połączenie transportowe, a usługa SignalR natychmiast stwierdza, że połączenie zostanie utracone. W innych scenariuszach ani interfejs API połączenia transportowego, ani usługa SignalR nie rozpoznają natychmiast, że łączność została utracona. W przypadku wszystkich transportów z wyjątkiem długiego sondowania klient usługi SignalR używa funkcji o nazwie keepalive , aby sprawdzić, czy nie można wykryć łączności z interfejsem API transportu. Aby uzyskać informacje na temat długich połączeń sondowania, zobacz Limit czasu i ustawienia utrzymania aktywności w dalszej części tego tematu.
Gdy połączenie jest nieaktywne, serwer okresowo wysyła pakiet keepalive do klienta. Od daty zapisu tego artykułu domyślna częstotliwość jest co 10 sekund. Nasłuchiwanie tych pakietów umożliwia klientom określenie, czy występuje problem z połączeniem. Jeśli pakiet keepalive nie jest odbierany w oczekiwany sposób, po krótkim czasie klient zakłada, że występują problemy z połączeniem, takie jak spowolnienie lub przerwy. Jeśli utrzymanie aktywności nadal nie jest odbierane po dłuższym czasie, klient zakłada, że połączenie zostało porzucone i rozpoczyna próbę ponownego nawiązania połączenia.
Na poniższym diagramie przedstawiono zdarzenia klienta i serwera, które są zgłaszane w typowym scenariuszu, gdy występują problemy z połączeniem fizycznym, które nie są natychmiast rozpoznawane przez interfejs API transportu. Diagram ma zastosowanie do następujących okoliczności:
- Transport to WebSockets, forever frame lub zdarzenia wysyłane przez serwer.
- Istnieją różne okresy przerw w działaniu połączenia sieciowego fizycznego.
- Interfejs API transportu nie zdaje sobie sprawy z przerw, więc usługa SignalR opiera się na funkcji utrzymania aktywności, aby je wykryć.
Jeśli klient przejdzie w tryb ponownego połączenia, ale nie może ustanowić połączenia transportowego w ramach limitu czasu rozłączenia, serwer przerywa połączenie usługi SignalR. W takim przypadku serwer wykonuje metodę centrum OnDisconnected
i kolejkuje komunikat rozłączenia w celu wysłania do klienta w przypadku, gdy klient zarządza nawiązaniem połączenia później. Jeśli klient następnie ponownie nawiązie połączenie, otrzyma polecenie rozłączenia i wywoła metodę Stop
. W tym scenariuszu OnReconnected
nie jest wykonywane, gdy klient ponownie się łączy i OnDisconnected
nie jest wykonywany, gdy klient wywołuje polecenie Stop
. Na poniższym diagramie przedstawiono ten scenariusz.
Zdarzenia okresu istnienia połączenia usługi SignalR, które mogą być zgłaszane na kliencie, są następujące:
ConnectionSlow
zdarzenie klienta.Podniesione, gdy od czasu odebrania ostatniego komunikatu lub polecenia ping na żywo czas utrzymywania aktywności upłynął wstępnie ustawiony odsetek okresu przekroczenia limitu czasu utrzymania. Domyślny okres ostrzegawczy limitu czasu utrzymania aktywności wynosi 2/3 limitu czasu utrzymania. Limit czasu utrzymania aktywności wynosi 20 sekund, więc ostrzeżenie występuje około 13 sekund.
Domyślnie serwer wysyła polecenia ping na żywo co 10 sekund, a klient sprawdza, czy są wysyłane polecenia ping na żywo co 2 sekundy (jedna trzecia różnicy między wartością limitu czasu utrzymania aktywności a wartością ostrzeżenia o przekroczeniu limitu czasu utrzymania aktywności).
Jeśli interfejs API transportu zorientuje się o rozłączeniu, usługa SignalR może zostać poinformowana o rozłączeniu przed upływem limitu czasu utrzymania aktywności. W takim przypadku
ConnectionSlow
zdarzenie nie zostanie zgłoszone, a usługa SignalR przejdzie bezpośrednio doReconnecting
zdarzenia.Reconnecting
zdarzenie klienta.Zgłaszane, gdy (a) interfejs API transportu wykryje, że połączenie zostanie utracone lub (b) okres limitu czasu utrzymania aktywności minął od czasu odebrania ostatniego komunikatu lub polecenia ping na żywo. Kod klienta usługi SignalR rozpoczyna próbę ponownego nawiązania połączenia. To zdarzenie można obsłużyć, jeśli aplikacja ma podjąć jakąś akcję w przypadku utraty połączenia transportowego. Domyślny okres limitu czasu utrzymania aktywności wynosi obecnie 20 sekund.
Jeśli kod klienta próbuje wywołać metodę koncentratora, gdy usługa SignalR jest w trybie ponownego nawiązywania połączenia, usługa SignalR spróbuje wysłać polecenie. W większości przypadków takie próby nie powiedzą się, ale w pewnych okolicznościach mogą się odnieść sukces. W przypadku zdarzeń wysyłanych przez serwer, na zawsze ramek i długich transportów sondowania usługa SignalR używa dwóch kanałów komunikacyjnych, których klient używa do wysyłania komunikatów i jednego, którego używa do odbierania komunikatów. Kanał używany do odbierania jest trwale otwarty i jest to kanał, który jest zamykany po przerwaniu połączenia fizycznego. Kanał używany do wysyłania pozostaje dostępny, więc jeśli zostanie przywrócona łączność fizyczna, wywołanie metody od klienta do serwera może zakończyć się pomyślnie przed ponownym nawiązaniem kanału odbierania. Wartość zwracana nie zostanie odebrana, dopóki usługa SignalR nie otworzy ponownie kanału używanego do odbierania.
Reconnected
zdarzenie klienta.Podniesione, gdy połączenie transportowe zostanie ponownie nawiązane. Procedura
OnReconnected
obsługi zdarzeń w centrum jest wykonywana.Closed
zdarzenie klienta (disconnected
zdarzenie w języku JavaScript).Podniesiono, gdy okres przekroczenia limitu czasu rozłączenia wygaśnie, gdy kod klienta usługi SignalR próbuje ponownie nawiązać połączenie po utracie połączenia transportowego. Domyślny limit czasu rozłączenia wynosi 30 sekund. (To zdarzenie jest również zgłaszane po zakończeniu połączenia, ponieważ metoda jest wywoływana
Stop
).
Przerwy w połączeniu transportowym, które nie są wykrywane przez interfejs API transportu i nie opóźniają odbioru poleceń ping na żywo z serwera przez dłuższy czas niż okres ostrzeżenia o przekroczeniu limitu czasu utrzymania może nie spowodować zgłoszenia żadnych zdarzeń okresu istnienia połączenia.
Niektóre środowiska sieciowe celowo zamykają bezczynne połączenia, a inną funkcją pakietów keepalive jest pomoc w zapobieganiu temu, informując te sieci o tym, że połączenie usługi SignalR jest używane. W skrajnych przypadkach domyślna częstotliwość wysyłania poleceń ping na żywo może nie być wystarczająca, aby zapobiec zamkniętym połączeniom. W takim przypadku można skonfigurować polecenia ping na żywo do wysyłania częściej. Aby uzyskać więcej informacji, zobacz Limit czasu i ustawienia utrzymania aktywności w dalszej części tego tematu.
Uwaga
Ważne: Sekwencja zdarzeń opisanych tutaj nie jest gwarantowana. Usługa SignalR podejmuje każdą próbę podniesienia zdarzeń okresu istnienia połączenia w przewidywalny sposób zgodnie z tym schematem, ale istnieje wiele odmian zdarzeń sieciowych i wiele sposobów, w których podstawowe struktury komunikacji, takie jak interfejsy API transportu, obsługują je. Na przykład Reconnected
zdarzenie może nie zostać zgłoszone, gdy klient ponownie nawiązuje połączenie, lub OnConnected
program obsługi na serwerze może zostać uruchomiony, gdy próba nawiązania połączenia nie powiedzie się. W tym temacie opisano tylko efekty, które normalnie byłyby generowane przez określone typowe okoliczności.
Scenariusze rozłączania klienta
W kliencie przeglądarki kod klienta usługi SignalR, który utrzymuje połączenie usługi SignalR, jest uruchamiany w kontekście języka JavaScript strony internetowej. Dlatego połączenie usługi SignalR musi zakończyć się po przejściu z jednej strony do innej i dlatego istnieje wiele połączeń z wieloma identyfikatorami połączeń, jeśli łączysz się z wielu okien przeglądarki lub kart. Gdy użytkownik zamknie okno przeglądarki lub kartę albo przejdzie do nowej strony lub odświeży stronę, połączenie usługi SignalR natychmiast się kończy, ponieważ kod klienta usługi SignalR obsługuje to zdarzenie przeglądarki i wywołuje metodę Stop
. W tych scenariuszach lub na dowolnej platformie klienta, gdy aplikacja wywołuje Stop
metodę, OnDisconnected
program obsługi zdarzeń jest wykonywany natychmiast na serwerze, a klient zgłasza Closed
zdarzenie (zdarzenie ma nazwę disconnected
w języku JavaScript).
Jeśli aplikacja kliencka lub komputer, na którym działa, ulega awarii lub przechodzi w stan uśpienia (na przykład gdy użytkownik zamknie laptopa), serwer nie jest informowany o tym, co się stało. Jeśli chodzi o serwer wie, utrata klienta może być spowodowana przerwą w łączności, a klient może próbować ponownie nawiązać połączenie. W związku z tym w tych scenariuszach serwer czeka, aby dać klientowi szansę na ponowne nawiązanie połączenia i OnDisconnected
nie zostanie wykonany do momentu wygaśnięcia limitu czasu rozłączenia (domyślnie około 30 sekund). Na poniższym diagramie przedstawiono ten scenariusz.
Scenariusze rozłączania serwera
Gdy serwer przejdzie w tryb offline — uruchamia się ponownie, kończy się niepowodzeniem, recyklingu domeny aplikacji itp. — wynik może być podobny do utraconego połączenia lub interfejs API transportu i usługa SignalR może natychmiast wiedzieć, że serwer zniknął, a usługa SignalR może rozpocząć ponowne nawiązywanie połączenia bez wywoływania ConnectionSlow
zdarzenia. Jeśli klient przejdzie w tryb ponownego nawiązywania połączenia, a jeśli serwer odzyska lub uruchomi ponownie lub nowy serwer zostanie przełączony w tryb online przed upływem limitu czasu rozłączenia, klient ponownie nawiąż połączenie z przywróconym lub nowym serwerem. W takim przypadku połączenie usługi SignalR jest kontynuowane na kliencie i Reconnected
jest zgłaszane zdarzenie. Na pierwszym serwerze OnDisconnected
nigdy nie jest wykonywany, a na nowym serwerze jest wykonywany, OnReconnected
mimo że OnConnected
nigdy wcześniej nie został wykonany dla tego klienta na tym serwerze. (Efekt jest taki sam, jeśli klient ponownie nawiąże połączenie z tym samym serwerem po ponownym uruchomieniu lub ponownym uruchomieniu domeny aplikacji, ponieważ po ponownym uruchomieniu serwera nie ma pamięci wcześniejszej aktywności połączenia). Na poniższym diagramie przyjęto założenie, że interfejs API transportu natychmiast zorientuje się o utracie połączenia, więc ConnectionSlow
zdarzenie nie jest zgłaszane.
Limit czasu i ustawienia zachowania aktywności
Wartości domyślne ConnectionTimeout
, DisconnectTimeout
i KeepAlive
są odpowiednie dla większości scenariuszy, ale można je zmienić, jeśli środowisko ma specjalne potrzeby. Jeśli na przykład środowisko sieciowe zamyka połączenia bezczynne przez 5 sekund, może być konieczne zmniejszenie wartości utrzymania aktywności.
ConnectionTimeout
To ustawienie oznacza czas, przez jaki połączenie transportu jest otwarte i czeka na odpowiedź przed jego zamknięciem i otwarciem nowego połączenia. Wartość domyślna to 110 sekund.
To ustawienie ma zastosowanie tylko wtedy, gdy funkcja utrzymania aktywności jest wyłączona, co zwykle ma zastosowanie tylko do długiego transportu sondowania. Na poniższym diagramie przedstawiono wpływ tego ustawienia na długie połączenie komunikacyjne sondowania.
DisconnectTimeout
To ustawienie reprezentuje czas oczekiwania po utracie połączenia transportowego przed podniesieniem Disconnected
zdarzenia. Wartość domyślna to 30 sekund. Po ustawieniu DisconnectTimeout
parametru zostanie KeepAlive
automatycznie ustawiona wartość 1/3 wartości DisconnectTimeout
.
KeepAlive
To ustawienie reprezentuje czas oczekiwania przed wysłaniem pakietu keepalive za pośrednictwem bezczynnego połączenia. Wartość domyślna to 10 sekund. Ta wartość nie może być większa niż 1/3 DisconnectTimeout
wartości.
Jeśli chcesz ustawić wartości i DisconnectTimeout
KeepAlive
, ustaw wartość KeepAlive
po DisconnectTimeout
. KeepAlive
W przeciwnym razie ustawienie zostanie zastąpione, gdy DisconnectTimeout
automatycznie ustawi KeepAlive
wartość limitu czasu na 1/3.
Jeśli chcesz wyłączyć funkcję keepalive, ustaw wartość KeepAlive
null. Funkcja Keepalive jest automatycznie wyłączona dla długiego transportu sondowania.
Jak zmienić limit czasu i ustawienia utrzymania aktywności
Aby zmienić wartości domyślne tych ustawień, ustaw je w Application_Start
pliku Global.asax , jak pokazano w poniższym przykładzie. Wartości pokazane w przykładowym kodzie są takie same jak wartości domyślne.
protected void Application_Start(object sender, EventArgs e)
{
// Make long polling connections wait a maximum of 110 seconds for a
// response. When that time expires, trigger a timeout command and
// make the client reconnect.
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(110);
// Wait a maximum of 30 seconds after a transport connection is lost
// before raising the Disconnected event to terminate the SignalR connection.
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(30);
// For transports other than long polling, send a keepalive packet every
// 10 seconds.
// This value must be no more than 1/3 of the DisconnectTimeout value.
GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(10);
RouteTable.Routes.MapHubs();
}
Jak powiadomić użytkownika o rozłączeniach
W niektórych aplikacjach możesz wyświetlić użytkownikowi komunikat, gdy występują problemy z łącznością. Istnieje kilka opcji, aby dowiedzieć się, jak i kiedy to zrobić. Poniższe przykłady kodu są przeznaczone dla klienta JavaScript przy użyciu wygenerowanego serwera proxy.
Obsłuż zdarzenie,
connectionSlow
aby wyświetlić komunikat, gdy tylko usługa SignalR wie o problemach z połączeniem, zanim przejdzie do trybu ponownego nawiązywania połączenia.$.connection.hub.connectionSlow(function() { notifyUserOfConnectionProblem(); // Your function to notify user. });
Obsłuż zdarzenie,
reconnecting
aby wyświetlić komunikat, gdy usługa SignalR wie o rozłączeniu i przechodzi do trybu ponownego nawiązywania połączenia.$.connection.hub.reconnecting(function() { notifyUserOfTryingToReconnect(); // Your function to notify user. });
Obsłuż zdarzenie,
disconnected
aby wyświetlić komunikat po przekroczeniu limitu czasu próby ponownego nawiązania połączenia. W tym scenariuszu jedynym sposobem ponownego nawiązania połączenia z serwerem jest ponowne uruchomienie połączenia usługi SignalR przez wywołanieStart
metody , co spowoduje utworzenie nowego identyfikatora połączenia. Poniższy przykładowy kod używa flagi, aby upewnić się, że wysyłasz powiadomienie dopiero po ponownym połączeniu limitu czasu, a nie po normalnym zakończeniu połączenia usługi SignalR spowodowanego wywołaniemStop
metody.var tryingToReconnect = false; $.connection.hub.reconnecting(function() { tryingToReconnect = true; }); $.connection.hub.reconnected(function() { tryingToReconnect = false; }); $.connection.hub.disconnected(function() { if(tryingToReconnect) { notifyUserOfDisconnect(); // Your function to notify user. } });
Jak stale ponownie łączyć się
W niektórych aplikacjach możesz automatycznie ponownie ustanowić połączenie po jego utracie, a próba ponownego nawiązania połączenia przekroczyła limit czasu. W tym celu można wywołać metodę Start
z Closed
programu obsługi zdarzeń (disconnected
program obsługi zdarzeń na klientach JavaScript). Możesz poczekać pewien czas przed wywołaniem Start
, aby uniknąć zbyt częstego wykonywania tej czynności, gdy serwer lub połączenie fizyczne są niedostępne. Poniższy przykład kodu jest przeznaczony dla klienta JavaScript przy użyciu wygenerowanego serwera proxy.
$.connection.hub.disconnected(function() {
setTimeout(function() {
$.connection.hub.start();
}, 5000); // Restart connection after 5 seconds.
});
Potencjalnym problemem, który należy wziąć pod uwagę w klientach mobilnych, jest to, że ciągłe próby ponownego połączenia, gdy serwer lub połączenie fizyczne nie jest dostępne, może spowodować niepotrzebne opróżnienie baterii.
Jak rozłączyć klienta w kodzie serwera
Usługa SignalR w wersji 2 nie ma wbudowanego interfejsu API serwera do odłączania klientów. Istnieją plany dodawania tej funkcji w przyszłości. W bieżącej wersji usługi SignalR najprostszym sposobem odłączenia klienta od serwera jest zaimplementowanie metody rozłączenia na kliencie i wywołanie tej metody z serwera. Poniższy przykładowy kod przedstawia metodę rozłączenia klienta JavaScript przy użyciu wygenerowanego serwera proxy.
var myHubProxy = $.connection.myHub
myHubProxy.client.stopClient = function() {
$.connection.hub.stop();
};
Ostrzeżenie
Zabezpieczenia — ani ta metoda rozłączania klientów, ani proponowanego wbudowanego interfejsu API nie będzie dotyczyć scenariusza zhakowanych klientów, którzy uruchamiają złośliwy kod, ponieważ klienci mogą ponownie nawiązać połączenie lub kod zhakowany może usunąć stopClient
metodę lub zmienić to, co robi. Odpowiednie miejsce do zaimplementowania ochrony typu "odmowa usługi" stanowej (DOS) nie znajduje się w strukturze ani w warstwie serwera, ale raczej w infrastrukturze frontonu.
Wykrywanie przyczyny rozłączenia
Usługa SignalR 2.1 dodaje przeciążenie do zdarzenia serwera OnDisconnect
, które wskazuje, czy klient celowo rozłączył się, a nie przekroczył limit czasu. Parametr StopCalled
ma wartość true, jeśli klient jawnie zamknął połączenie. W języku JavaScript, jeśli błąd serwera spowodował rozłączenie klienta, informacje o błędzie zostaną przekazane do klienta jako $.connection.hub.lastError
.
Kod serwera C#: stopCalled
parametr
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
if (stopCalled)
{
Console.WriteLine(String.Format("Client {0} explicitly closed the connection.", Context.ConnectionId));
}
else
{
Console.WriteLine(String.Format("Client {0} timed out .", Context.ConnectionId));
}
return base.OnDisconnected(stopCalled);
}
Kod klienta JavaScript: dostęp lastError
do zdarzenia disconnect
.
$.connection.hub.disconnected(function () {
if ($.connection.hub.lastError)
{ alert("Disconnected. Reason: " + $.connection.hub.lastError.message); }
});