C# OpenVPN State Observer: เฝ้าดูเซสชัน ไม่ใช่การ์ดเครือข่าย
NetworkAvailabilityChanged ไม่ใช่เหตุการณ์ VPN อ่านสตรีมสถานะของไคลเอนต์ที่เป็นเจ้าของอุโมงค์ ป้องกันการตรวจสอบที่ล้าสมัย และเผยแพร่ความพร้อมต่อการเชื่อมต่อ
แอปพลิเคชันของคุณยังทำงานอยู่ขณะที่อุโมงค์ตาย Wi-Fi ยังเปิดอยู่ อินเทอร์เน็ตยังตอบสนอง และ API ส่วนตัวที่แอปพึ่งพาอยู่ก็เข้าถึงไม่ได้แล้ว เหตุการณ์ .NET ที่ผู้คนมักหันไปใช้ตรงนี้ NetworkAvailabilityChangedไม่ได้อธิบายสถานการณ์นั้นเลย มันรายงานการเปลี่ยนแปลงของสถานะรวมของเครื่อง และสถานะนั้นอาจยังเป็นจริงตลอดการตัดและเชื่อมต่อ VPN ใหม่ ผู้เฝ้าดูต้องเฝ้าดูไคลเอนต์ที่เป็นเจ้าของอุโมงค์ ไม่ใช่บทสรุปของสแตกเครือข่าย
ความพร้อมใช้งานเป็นค่าลวม ไม่ใช่อุโมงค์ของคุณ
NetworkAvailabilityChanged จะถูกกระตุ้นเมื่อคำตอบความพร้อมใช้งานรวมของเครื่องเปลี่ยน และคำตอบนั้นนับอินเทอร์เฟซที่ทำงานอยู่ทั้งหมดยกเว้น loopback หรืออุโมงค์
การที่ VPN หลุดขณะ Wi-Fi ทำงานอยู่ไม่เปลี่ยนอะไรที่มันวัด นั่นคือเหตุผลที่เหตุการณ์อาจเงียบสนิทตลอดความล้มเหลวที่คุณสนใจ
สตรีมสถานะเป็นของไคลเอนต์ที่เป็นเจ้าของอุโมงค์
ระบุว่าองค์ประกอบใดเป็นเจ้าของการเชื่อมต่อ: GUI หรือบริการของ OpenVPN, OpenVPN Connect หรือโปรเซสที่แอปพลิเคชันของคุณเริ่มและควบคุม เหล่านี้เป็นเจ้าของต่างกันที่มีอินเทอร์เฟซที่รองรับต่างกัน และผู้เฝ้าดูต้องใช้อันที่ตรงกับการติดตั้ง สำหรับโปรเซส OpenVPN ที่คุณได้รับอนุญาตให้ผสานรวมด้วย อินเทอร์เฟซการจัดการจะรายงานสถานะปัจจุบัน ประวัติ และการแจ้งเตือนแบบเรียลไทม์ วิเคราะห์ข้อความแบบมีโครงสร้างที่มีเอกสารแทนการค้นหาคำว่า connected ในคำอธิบาย GUI ที่แปลแล้ว
ช่องทางการจัดการเป็นพื้นผิวควบคุมที่มีสิทธิ์พิเศษ ดังนั้นอย่าเปิดตัวรับฟังใหม่และอย่าแย่งช่องทางที่ GUI ถืออยู่แล้ว
ตัวป้องกันรุ่นหยุดผลลัพธ์ที่ล้าสมัย
ทุกการสังเกตเป็นของการพยายามเชื่อมต่อครั้งใดครั้งหนึ่ง เพิ่มตัวนับรุ่นเมื่อความพยายามใหม่เริ่ม เมื่อช่องทางหายไป และเมื่อไคลเอนต์รายงานการออก
ลองพิจารณาการตรวจสอบที่เริ่มระหว่างการเชื่อมต่อ A อุโมงค์ล่ม การเชื่อมต่อ B เริ่ม แล้วความสำเร็จ HTTP ที่ล่าช้าของ A ก็มาถึง หากไม่มีตัวป้องกัน ผลลัพธ์เก่าจะทำให้หน้าจอเป็นสีเขียวขณะที่ B ยังตรวจสอบสิทธิ์อยู่ การยกเลิกช่วยลดงานที่สูญเปล่า และการตรวจรุ่นคือสิ่งที่หยุดการเสร็จสิ้นที่ล้าสมัยไม่ให้กลายเป็นสถานะปัจจุบัน
var generation = _generation;
var reachable = await ProbeAsync(token);
if (generation != _generation) return;
Publish(reachable);
ใช้กฎเดียวกันกับการส่งไปยัง UI เพราะการอัปเดตที่ผ่านมาร์แชลอาจมาถึงหลังจากรุ่นเดินหน้าไปแล้ว
การเริ่มต้นและการเชื่อมต่อใหม่เป็นวัฏจักรชีวิตเดียว
ถือว่าการเชื่อมต่อครั้งแรก การเชื่อมต่อใหม่ และการสูญเสียช่องทางเป็นวัฏจักรชีวิตเดียวด้วยชุดกฎเดียว
- อ่านสถานะปัจจุบันและสมัครรับการแจ้งเตือนในขั้นตอนเดียวในที่ที่อินเทอร์เฟซอนุญาต
- ติดแท็กทุกการสังเกตด้วยตัวระบุการเชื่อมต่อและรุ่น
- ทำให้ความพร้อมใช้เป็นโมฆะเมื่อเชื่อมต่อใหม่ ออก หรือช่องทางการสังเกตหายไป
- ตรวจสอบทรัพยากรส่วนตัวหลังจากเจ้าของรายงานว่าการเริ่มต้นเสร็จสมบูรณ์แล้วเท่านั้น
- เผยแพร่เฉพาะผลลัพธ์ที่ยังเป็นของรุ่นปัจจุบัน
ช่องทางที่หายไปหมายถึงไม่ทราบ ไม่ใช่ตัดการเชื่อมต่อ การรายงานว่าไม่ทราบนั้นซื่อสัตย์กว่าการรายงานการตัดการเชื่อมต่อที่คุณพิสูจน์ไม่ได้ และหยุดตรรกะการลองใหม่ไม่ให้ลงมือตามการคาดเดา
รายงานหลักฐาน ไม่ใช่บูลีน
คืนสถานะเซสชันที่ตั้งชื่อและความพร้อมของทรัพยากรเป็นค่าที่แยกจากกัน แต่ละค่ามีอายุ ผู้บริโภคที่ต้องตัดสินใจอะไรบางอย่างจะเห็นได้ว่าการตรวจสอบที่สำเร็จครั้งล่าสุดมีอายุสี่สิบวินาที ซึ่งเป็นข้อมูลที่ต่างจากข้อมูลสด
การค้นหา IP สาธารณะไม่ใช่หลักฐานว่า API ส่วนตัวใช้เส้นทางที่ต้องการ ดังนั้นอย่านำเสนอราวกับว่าเป็นเช่นนั้น
เก็บการบังคับใช้ไว้นอกผู้เฝ้าดู
คอลแบ็กทำงานหลังจากเหตุการณ์เกิดขึ้น มันไม่สามารถรับประกันได้ว่าจะไม่มีแพ็กเก็ตออกจากเครื่องระหว่างเหตุการณ์และตัวจัดการ หากการออกแบบต้องการการบล็อก นโยบายเครือข่ายต้องเป็นผู้จัดหา และหน้าที่ของผู้เฝ้าดูคืออธิบายหลักฐานให้ผู้เรียก การผสมทั้งสองอย่างจะสร้างโค้ดที่คิดว่าตัวเองเป็นไฟร์วอลล์เพราะถือบูลีนไว้ ทำให้ชั้นการบังคับใช้น่าเบื่อและทดสอบได้ และปล่อยให้ผู้เฝ้าดูเป็นผู้อ่านต่อไป
แล้วคำถามของ UI ก็ง่ายขึ้น: แสดงสิ่งที่รู้พร้อมอายุ และบอกว่าไม่ทราบเมื่อเป็นเช่นนั้น