Aplikasi Anda tetap berjalan saat terowongan mati. Wi-Fi masih menyala, internet masih menjawab, dan API privat yang menjadi sandaran aplikasi telah menjadi tak terjangkau. Peristiwa .NET yang biasanya dijangkau orang di sini, NetworkAvailabilityChanged, sama sekali tidak menggambarkan situasi itu. Peristiwa itu melaporkan perubahan kondisi agregat mesin, dan kondisi itu bisa tetap benar sepanjang pemutusan dan penyambungan ulang VPN. Pengamat harus mengawasi klien yang memiliki terowongan, bukan ringkasan tumpukan jaringan tentangnya.

Ketersediaan adalah agregat, bukan terowongan Anda

NetworkAvailabilityChanged terpicu ketika jawaban ketersediaan agregat mesin berubah, dan jawaban itu menghitung setiap antarmuka aktif selain loopback atau terowongan.

Putusnya VPN saat Wi-Fi menyala tidak mengubah apa pun yang diukurnya, karena itulah peristiwa itu bisa tetap diam tepat selama kegagalan yang Anda pedulikan.

Aliran status milik klien yang memiliki terowongan

Identifikasi komponen mana yang memiliki koneksi: GUI atau layanan OpenVPN, OpenVPN Connect, atau proses yang dijalankan dan dikendalikan aplikasi Anda. Itu adalah pemilik berbeda dengan antarmuka didukung yang berbeda, dan pengamat harus memakai yang sesuai dengan penerapan. Untuk proses OpenVPN yang Anda berwenang berintegrasi dengannya, antarmuka manajemen melaporkan status saat ini, riwayat, dan notifikasi waktu nyata. Analisis pesan terstruktur yang terdokumentasi alih-alih mencari kata connected di keterangan GUI yang dilokalkan.

Kanal manajemen adalah permukaan kendali istimewa, jadi jangan buka pendengar baru atau berebut dengan GUI untuk kanal yang sudah dipegangnya.

Penjaga generasi menghentikan hasil basi

Setiap pengamatan milik upaya koneksi tertentu. Naikkan penghitung generasi saat upaya baru dimulai, saat kanal hilang, dan saat klien melaporkan keluar.

Pertimbangkan pemeriksaan yang dimulai selama koneksi A. Terowongan putus, koneksi B dimulai, lalu keberhasilan HTTP A yang tertunda tiba sesudahnya. Tanpa penjaga, hasil lama itu membuat tampilan hijau sementara B masih mengautentikasi. Pembatalan mengurangi pekerjaan terbuang, dan pemeriksaan generasi itulah yang mencegah penyelesaian usang menjadi status saat ini:

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

Terapkan aturan yang sama di sekitar pengiriman ke UI, karena pembaruan yang dimarshalikan bisa tiba setelah generasi bergerak maju.

Inisialisasi dan penyambungan ulang adalah satu siklus hidup

Perlakukan koneksi pertama, penyambungan ulang, dan hilangnya kanal sebagai satu siklus hidup dengan satu set aturan:

  • Baca status saat ini dan berlangganan notifikasi dalam satu langkah di mana antarmuka mengizinkannya.
  • Tandai setiap pengamatan dengan identitas koneksi dan generasi.
  • Batalkan kesiapan saat penyambungan ulang, keluar, atau kanal pengamatan hilang.
  • Periksa sumber daya privat hanya setelah pemilik melaporkan inisialisasi selesai.
  • Terbitkan hanya hasil yang masih milik generasi saat ini.

Kanal yang hilang berarti tidak diketahui, bukan terputus. Melaporkan tidak diketahui lebih jujur daripada melaporkan pemutusan yang tidak dapat Anda buktikan, dan itu mencegah logika percobaan ulang bertindak atas dugaan.

Laporkan bukti, bukan boolean

Kembalikan status sesi bernama dan kesiapan sumber daya sebagai nilai terpisah, masing-masing membawa usia. Konsumen yang harus memutuskan sesuatu lalu dapat melihat bahwa pemeriksaan sukses terakhir berusia empat puluh detik, yang merupakan informasi berbeda dari yang segar.

Pencarian IP publik bukan bukti bahwa API privat menggunakan rute yang diperlukan, jadi jangan menyajikannya seolah-olah begitu.

Jaga penegakan di luar pengamat

Panggilan balik berjalan setelah kejadian. Itu tidak dapat menjamin tidak ada paket yang meninggalkan mesin antara peristiwa dan penangan. Jika desain memerlukan pemblokiran, kebijakan jaringan harus menyediakannya, dan tugas pengamat adalah menjelaskan bukti kepada pemanggilnya. Mencampur keduanya menghasilkan kode yang mengira dirinya firewall karena memegang boolean. Jaga lapisan penegakan tetap membosankan dan dapat diuji, dan biarkan pengamat tetap menjadi pembaca.

Maka pertanyaan UI menjadi sederhana: tunjukkan apa yang diketahui, beserta usianya, dan katakan tidak diketahui bila memang demikian.

Artikel terkait