C# OpenVPN-tilstandsobservatør: overvak økta, ikkje nettverkskortet
NetworkAvailabilityChanged er ikkje ei VPN-hending. Les tilstandsstraumen frå klienten som eig tunnelen, vern mot utdaterte probar og publiser beredskap per tilkopling.
Applikasjonen din held fram med å verke medan tunnelen døyr. Wi-Fi er framleis oppe, internett svarar framleis, og det private API-et appen er avhengig av, har blitt utilgjengeleg. .NET-hendinga folk vanlegvis grip til her, NetworkAvailabilityChanged, skildrar ikkje den situasjonen i det heile. Ho rapporterer ei endring i den samla tilstanden til maskina, og den tilstanden kan halde fram med å vere sann gjennom ein VPN-fråkopling og attkopling. Ein observatør må overvake klienten som eig tunnelen, ikkje samandraget frå nettverksstakken.
Tilgjenge er eit aggregat, ikkje tunnelen din
NetworkAvailabilityChanged blir utløyst når det samla tilgjenge-svaret til maskina endrar seg, og det svaret tel kvart aktivt grensesnitt utanom loopback eller ein tunnel.
Eit VPN-brot medan Wi-Fi er oppe endrar ingenting av det ho måler, difor kan hendinga halde seg taus gjennom nettopp feilen du bryr deg om.
Tilstandsstraumen høyrer til klienten som eig tunnelen
Finst ut kva komponent som eig tilkoplinga: OpenVPN GUI eller -tenesta, OpenVPN Connect, eller ein prosess applikasjonen din starta og kontrollerer. Dette er ulike eigarar med ulike støtta grensesnitt, og observatøren må bruke det som passar til utrullinga. For ein OpenVPN-prosess du har løyve til å integrere med, rapporterer administrasjonsgrensesnittet gjeldande tilstand, ei historikk og sanntidsvarsel. Analyser dei dokumenterte strukturerte meldingane i staden for å leite etter ordet connected i ein lokalisert GUI-tekst.
Administrasjonskanalen er ei privilegert kontrollflate, så ikkje opne ein ny lyttar og ikkje kjempe med GUI-en om ein kanal ho alt har.
Generasjonsvaktar stoppar utdaterte resultat
Kvar observasjon høyrer til eit bestemt tilkoplingsforsøk. Auk ein generasjonsteljar når eit nytt forsøk startar, når kanalen blir mist og når klienten rapporterer avslutning.
Tenk på ein probe som starta under tilkopling A. Tunnelen fell, tilkopling B byrjar, og deretter kjem den forseinka HTTP-suksessen til A. Utan ei vakt gjer det gamle resultatet skjermen grøn medan B framleis autentiserer. Avbryting reduserer bortkasta arbeid, og generasjonskontrollen er det som hindrar ei utdatert fullføring i å bli gjeldande tilstand:
var generation = _generation;
var reachable = await ProbeAsync(token);
if (generation != _generation) return;
Publish(reachable);
Bruk same regel rundt UI-utsendinga, fordi den marsjalliserte oppdateringa kan kome etter at generasjonen har flytta seg vidare.
Initialisering og attkopling er ein livssyklus
Handter første tilkopling, attkopling og kanaltap som ein livssyklus med eitt regelsett:
- Les gjeldande tilstand og abonner på varsel i eitt steg der grensesnittet tillet det.
- Merk kvar observasjon med identiteten til tilkoplinga og generasjonen.
- Gjer beredskapen ugyldig ved attkopling, avslutning eller ein tapt observasjonskanal.
- Prob det private ressursen først etter at eigaren rapporterer at initialiseringa er fullført.
- Publiser berre resultat som framleis høyrer til gjeldande generasjon.
Ein tapt kanal tyder ukjend, ikkje fråkopia. Å rapportere ukjend er ærlegare enn å rapportere ei fråkopling du ikkje kan bevise, og det hindrar gjenforsk-logikken i å handle på ei gjetting.
Rapporter bevis, ikkje ein boolean
Returner den namngjetne sesjonstilstanden og ressurberedskapen som separate verdiar, kvar med ein alder. Ein forbrukar som må avgjere noko, kan då sjå at den siste vellukka proben er førti sekund gammal, noko som er annan informasjon enn ein fersk.
Eit oppslag av offentleg IP er ikkje bevis for at eit privat API brukte den påkravde ruta, så ikkje presenter det som om det var det.
Hald handhevinga utanfor observatøren
Ein callback køyrer i etterkant. Han kan ikkje garantere at ingen pakke forlét maskina mellom hendinga og handteraren. Viss designet krev blokkering, må nettverkspolicyen levere det, og jobben til observatøren er å forklare bevisa til den som kallar. Å blande dei to gjev kode som trur han er ein brannmur fordi han held ein boolean. Hald handhevingslaget kjedeleg og testbart, og lat observatøren halde fram som lesar.
Då blir UI-spørsmålet enkelt: vis det som er kjent, med alderen sin, og sei ukjend når det er tilfelle.