Twoja aplikacja nadal działa, gdy tunel umiera. Wi-Fi jest włączone, internet nadal odpowiada, a prywatne API, od którego zależy aplikacja, stało się nieosiągalne. Zdarzenie .NET, po które ludzie zwykle tu sięgają, NetworkAvailabilityChanged, w ogóle nie opisuje tej sytuacji. Zgłasza zmianę zagregowanego stanu maszyny, a ten stan może pozostać prawdziwy podczas rozłączenia i ponownego połączenia VPN. Obserwator musi pilnować klienta będącego właścicielem tunelu, a nie podsumowania stosu sieciowego.

Dostępność jest agregatem, a nie twoim tunelem

NetworkAvailabilityChanged uruchamia się, gdy zmieni się zagregowana odpowiedź maszyny o dostępności, a ta odpowiedź liczy każdy aktywny interfejs poza loopbackiem lub tunelem.

Awaria VPN przy włączonym Wi-Fi nie zmienia niczego, co mierzy, dlatego zdarzenie może milczeć dokładnie podczas awarii, na której ci zależy.

Strumień stanu należy do klienta będącego właścicielem tunelu

Ustal, który komponent jest właścicielem połączenia: GUI lub usługa OpenVPN, OpenVPN Connect albo proces uruchomiony i kontrolowany przez twoją aplikację. To różni właściciele z różnymi obsługiwanymi interfejsami, a obserwator musi użyć tego, który pasuje do wdrożenia. Dla procesu OpenVPN, z którym masz uprawnienie do integracji, interfejs zarządzania raportuje bieżący stan, historię i powiadomienia w czasie rzeczywistym. Analizuj udokumentowane komunikaty strukturalne, zamiast szukać słowa connected w zlokalizowanym podpisie GUI.

Kanał zarządzania to uprzywilejowana powierzchnia sterowania, więc nie otwieraj nowego nasłuchu i nie walcz z GUI o kanał, który już posiada.

Strażnicy generacji zatrzymują nieaktualne wyniki

Każda obserwacja należy do konkretnej próby połączenia. Zwiększ licznik generacji, gdy zaczyna się nowa próba, gdy kanał zostaje utracony i gdy klient zgłasza wyjście.

Rozważ sondę uruchomioną podczas połączenia A. Tunel pada, zaczyna się połączenie B, a potem nadchodzi opóźniony sukces HTTP od A. Bez strażnika ten stary wynik zmienia wyświetlacz na zielony, podczas gdy B wciąż się uwierzytelnia. Anulowanie ogranicza zmarnowaną pracę, a sprawdzenie generacji jest tym, co nie pozwala nieaktualnemu ukończeniu stać się bieżącym stanem:

var generation = _generation;
var reachable = await ProbeAsync(token);
if (generation != _generation) return;
Publish(reachable);

Zastosuj tę samą regułę wokół wysyłki do UI, ponieważ zmarshalizowana aktualizacja może przyjść po tym, jak generacja poszła dalej.

Inicjalizacja i ponowne połączenie to jeden cykl życia

Traktuj pierwsze połączenie, ponowne połączenie i utratę kanału jako jeden cykl życia z jednym zestawem reguł:

  • Odczytaj bieżący stan i zasubskrybuj powiadomienia w jednym kroku, tam gdzie interfejs na to pozwala.
  • Oznacz każdą obserwację tożsamością połączenia i generacją.
  • Unieważnij gotowość przy ponownym połączeniu, wyjściu lub utraconym kanale obserwacji.
  • Sondę prywatnego zasobu wykonaj dopiero po zgłoszeniu przez właściciela zakończenia inicjalizacji.
  • Publikuj tylko wyniki, które nadal należą do bieżącej generacji.

Utracony kanał oznacza nieznane, a nie rozłączone. Zgłaszanie nieznanego jest uczciwsze niż zgłaszanie rozłączenia, którego nie możesz udowodnić, i powstrzymuje logikę ponawiania przed działaniem na podstawie domysłu.

Raportuj dowody, nie wartość logiczną

Zwróć nazwany stan sesji i gotowość zasobu jako osobne wartości, każdą z wiekiem. Konsument, który musi coś zdecydować, może wtedy zobaczyć, że ostatnia udana sonda ma czterdzieści sekund, co jest inną informacją niż świeża.

Wyszukanie publicznego IP nie jest dowodem, że prywatne API użyło wymaganej trasy, więc nie przedstawiaj tego tak, jakby nim było.

Trzymaj egzekwowanie poza obserwatorem

Wywołanie zwrotne działa po fakcie. Nie może zagwarantować, że między zdarzeniem a procedurą obsługi żaden pakiet nie opuścił maszyny. Jeśli projekt wymaga blokowania, musi je zapewnić polityka sieciowa, a zadaniem obserwatora jest wyjaśnić dowody swojemu wywołującemu. Mieszanie obu daje kod, który uważa się za firewall, bo trzyma wartość logiczną. Trzymaj warstwę egzekwowania nudną i testowalną, a obserwator niech pozostanie czytelnikiem.

Wtedy pytanie o UI staje się proste: pokaż, co jest znane, wraz z jego wiekiem, i powiedz nieznane, gdy tak jest.

Powiązane artykuły