C# OpenVPN-stata observanto: observu la seancon, ne la retkarton
NetworkAvailabilityChanged ne estas VPN-evento. Legu la statan fluon de la posedanta kliento, gardu kontraŭ kadukaj provoj kaj publikigu pretecon por ĉiu konekto.
Via aplikaĵo daŭre funkcias dum la tunelo mortas. Wi-Fi ankoraŭ funkcias, la interreto ankoraŭ respondas, kaj la privata API, de kiu la aplikaĵo dependas, fariĝis neatingebla. La .NET-evento, al kiu homoj kutime turniĝas ĉi tie, NetworkAvailabilityChanged, tute ne priskribas tiun situacion. Ĝi raportas ŝanĝon en la agregata stato de la maŝino, kaj tiu stato povas resti vera tra VPN-malkonekto kaj rekonekto. Observanto devas observi la klienton, kiu posedas la tunelon, ne la resumon de la reta stako pri ĝi.
Disponebleco estas agregato, ne via tunelo
NetworkAvailabilityChanged ekbrulas kiam la agregata disponebleca respondo de la maŝino ŝanĝiĝas, kaj tiu respondo kalkulas ĉiun aktivan interfacon krom loopback aŭ tunelo.
VPN-falo dum Wi-Fi funkcias ŝanĝas nenion, kion ĝi mezuras, tial la evento povas resti silenta ĝuste dum la fiasko, kiu gravas al vi.
La stata fluo apartenas al la kliento, kiu posedas la tunelon
Identigu, kiu komponanto posedas la konekton: la OpenVPN-GUI aŭ servo, OpenVPN Connect, aŭ procezo, kiun via aplikaĵo lanĉis kaj regas. Tiuj estas malsamaj posedantoj kun malsamaj subtenataj interfacoj, kaj la observanto devas uzi tiun, kiu kongruas kun la deplojo. Por OpenVPN-procezo, kun kiu vi rajtas integriĝi, la administra interfaco raportas la nunan staton, historion kaj realtempajn sciigojn. Analizu la dokumentitajn strukturitajn mesaĝojn anstataŭ serĉi la vorton connected en lokalizita GUI-titolo.
La administra kanalo estas privilegia rega surfaco, do ne malfermu novan aŭskultanton kaj ne disputu kun la GUI pri kanalo, kiun ĝi jam tenas.
Generaciaj gardistoj haltigas kadukajn rezultojn
Ĉiu observo apartenas al specifa konekta provo. Pliigu generacian nombrilon kiam nova provo komenciĝas, kiam la kanalo perdiĝas kaj kiam la kliento raportas eliron.
Konsideru provon komencitan dum konekto A. La tunelo falas, konekto B komenciĝas, kaj poste alvenas la prokrastita HTTP-sukceso de A. Sen gardisto, tiu malnova rezulto verdigas la ekranon dum B ankoraŭ aŭtentikigas. Nuligo reduktas malŝparitan laboron, kaj la generacia kontrolo estas tio, kio malhelpas kadukan finiĝon fariĝi nuna stato:
var generation = _generation;
var reachable = await ProbeAsync(token);
if (generation != _generation) return;
Publish(reachable);
Apliku la saman regulon ĉirkaŭ la UI-sendo, ĉar la marŝalita ĝisdatigo povas alveni post kiam la generacio moviĝis antaŭen.
Inicializo kaj rekonekto estas unu vivociklo
Traktu unuan konekton, rekonekton kaj kanalan perdon kiel unu vivociklon kun unu aro da reguloj:
- Legu la nunan staton kaj abonu al sciigoj en unu paŝo, kie la interfaco tion permesas.
- Marku ĉiun observon per la konekta identeco kaj la generacio.
- Senvalidigu pretecon ĉe rekonekto, eliro aŭ perdita observa kanalo.
- Provu la privatan rimedon nur post kiam la posedanto raportas finitan inicializon.
- Publikigu nur rezultojn, kiuj ankoraŭ apartenas al la nuna generacio.
Perdita kanalo signifas nekonata, ne malkonektita. Raporti nekonatan estas pli honesta ol raporti malkonekton, kiun vi ne povas pruvi, kaj ĝi malhelpas la rekloprov-logikon agi laŭ konjekto.
Raportu pruvojn, ne bulean valoron
Redonu la nomitan seancon-staton kaj la rimedan pretecon kiel apartajn valorojn, ĉiun kun aĝo. Konsumanto, kiu devas decidi ion, povas tiam vidi, ke la lasta sukcesa provo aĝas kvardek sekundojn, kio estas alia informo ol freŝa.
Serĉo de publika IP ne estas pruvo, ke privata API uzis la postulatan itineron, do ne prezentu ĝin kvazaŭ ĝi estus.
Tenadu plenumadon ekster la observanto
Reverko ruliĝas post la fakto. Ĝi ne povas garantii, ke neniu paketo forlasis la maŝinon inter la evento kaj la traktilo. Se la dezajno postulas blokadon, la reta politiko devas provizi ĝin, kaj la tasko de la observanto estas klarigi la pruvojn al sia alvokanto. Miksi la du produktas kodon, kiu kredas esti fajroŝirmilo ĉar ĝi tenas bulean valoron. Tenu la plenumtavolon enuiga kaj testeble, kaj lasu la observanton resti leganto.
Tiam la UI-demando fariĝas simpla: montru tion, kio estas konata, kun ĝia aĝo, kaj diru nekonata kiam ĝi estas tia.