Din applikation fortsætter med at virke, mens tunnelen dør. Wi-Fi er stadig oppe, internettet svarer stadig, og det private API, som appen afhænger af, er blevet utilgængeligt. Den .NET-hændelse, som folk normalt griber til her, NetworkAvailabilityChanged, beskriver slet ikke den situation. Den rapporterer en ændring i maskinens samlede tilstand, og den tilstand kan forblive sand gennem en VPN-afbrydelse og genopkobling. En observer skal overvåge den klient, der ejer tunnelen, ikke netværksstakkens resumé af den.

Tilgængelighed er et aggregat, ikke din tunnel

NetworkAvailabilityChanged udløses, når maskinens samlede tilgængelighedssvar ændres, og det svar tæller enhver aktiv grænseflade ud over loopback eller en tunnel.

Et VPN-nedbrud, mens Wi-Fi er oppe, ændrer intet af det, den måler, og derfor kan hændelsen forblive tavs gennem netop den fejl, du bekymrer dig om.

Tilstandsstrømmen tilhører den klient, der ejer tunnelen

Afgør, hvilken komponent der ejer forbindelsen: OpenVPN GUI eller -tjeneste, OpenVPN Connect, eller en proces som din applikation har startet og styrer. Det er forskellige ejere med forskellige understøttede grænseflader, og observeren skal bruge den, der passer til udrulningen. For en OpenVPN-proces, du har tilladelse til at integrere med, rapporterer styringsgrænsefladen den aktuelle tilstand, en historik og realtidsnotifikationer. Analysér de dokumenterede strukturerede meddelelser i stedet for at søge efter ordet connected i en lokaliseret GUI-tekst.

Styringskanalen er en privilegeret kontrolflade, så åbn ikke en ny lytter, og kæmp ikke med GUI'en om en kanal, den allerede holder.

Generationsværn stopper forældede resultater

Hver observation hører til et bestemt forbindelsesforsøg. Forøg en generationstæller, når et nyt forsøg starter, når kanalen mistes, og når klienten rapporterer afslutning.

Betragt en probe startet under forbindelse A. Tunnelen falder, forbindelse B begynder, og derefter ankommer A's forsinkede HTTP-succes. Uden et værn gør det gamle resultat skærmen grøn, mens B stadig autentificerer. Annullering reducerer spildt arbejde, og generationskontrollen er det, der forhindrer en forældet fuldførelse i at blive aktuel tilstand:

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

Anvend samme regel omkring UI-afsendelsen, fordi den marshallede opdatering kan ankomme, efter generationen er flyttet videre.

Initialisering og genopkobling er én livscyklus

Behandl første forbindelse, genopkobling og kanaltab som én livscyklus med ét regelsæt:

  • Læs den aktuelle tilstand, og abonnér på notifikationer i ét trin, hvor grænsefladen tillader det.
  • Mærk hver observation med forbindelsens identitet og generationen.
  • Ugyldiggør parathed ved genopkobling, afslutning eller en mistet observationskanal.
  • Prob det private ressource først, efter ejeren rapporterer, at initialiseringen er færdig.
  • Udgiv kun resultater, der stadig hører til den aktuelle generation.

En mistet kanal betyder ukendt, ikke afbrudt. At rapportere ukendt er mere ærligt end at rapportere en afbrydelse, du ikke kan bevise, og det forhindrer genforsøgslogikken i at handle på en gætning.

Rapportér evidens, ikke en boolean

Returnér den navngivne sessionstilstand og ressourceparatheden som separate værdier, hver med en alder. En forbruger, der skal beslutte noget, kan så se, at den sidste vellykkede probe er fyrre sekunder gammel, hvilket er en anden information end en frisk.

Et opslag af offentlig IP er ikke evidens for, at et privat API brugte den krævede rute, så præsentér det ikke, som om det var.

Hold håndhævelse uden for observeren

Et callback kører efter faktum. Det kan ikke garantere, at ingen pakke forlod maskinen mellem hændelsen og handleren. Hvis designet kræver blokering, skal netværkspolitikken levere det, og observerens opgave er at forklare evidensen for sin kalder. At blande de to producerer kode, der tror, den er en firewall, fordi den holder en boolean. Hold håndhævelseslaget kedeligt og testbart, og lad observeren forblive en læser.

Så bliver UI-spørgsmålet enkelt: vis, hvad der vides, med dets alder, og sig ukendt, når det er tilfældet.

Relaterede artikler