Udostępnij za pośrednictwem


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:

Wersje oprogramowania używane w tym temacie

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.

Diagram architektury usługi SignalR

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

rozłączenia transportu

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.

Zakłócenia transportu — przekroczenie limitu czasu serwera

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 do Reconnecting 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.

Błąd komputera klienckiego

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.

Awaria serwera i ponowne nawiązywanie połączenia Jeśli serwer nie stanie się dostępny w okresie przekroczenia limitu czasu rozłączenia, połączenie usługi SignalR kończy się. W tym scenariuszu zdarzenie "Zamknięte" ("odłączone" w klientach JavaScript) jest wywoływane na kliencie, ale "OnDisconnected" nigdy nie jest wywoływany na serwerze. Na poniższym diagramie przyjęto założenie, że interfejs API transportu nie wie o utraconym połączeniu, dlatego jest wykrywany przez funkcję utrzymania aktywności usługi SignalR i zgłaszane jest zdarzenie "ConnectionSlow".

Błąd serwera i przekroczenie limitu czasu

Limit czasu i ustawienia zachowania aktywności

Wartości domyślne ConnectionTimeout, DisconnectTimeouti 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.

Długie połączenie transportu sondowania

DisconnectTimeout

To ustawienie reprezentuje czas oczekiwania po utracie połączenia transportowego przed podniesieniem Disconnected zdarzenia. Wartość domyślna to 30 sekund. Po ustawieniu DisconnectTimeoutparametru 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łanie Start 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łaniem Stop 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); }
});