मेरे पास प्रस्तावित समाधान के साथ एक मुद्दा था, lookup
हमेशा अपेक्षित मूल्य वापस नहीं करता है।
यह डीएनएस कैशिंग के कारण है, कॉल का मूल्य कैश किया गया है और अगली कोशिश पर एक उचित कॉल करने का इरादा है यह कैश्ड मान को वापस देता है। बेशक यह यहां एक मुद्दा है क्योंकि इसका मतलब है कि अगर आप कनेक्टिविटी खो देते हैं और कॉल करते हैं तो lookup
यह कैश मूल्य को वापस कर सकता है जैसे कि आपके पास इंटरनेट था, और इसके विपरीत, यदि आप अपने इंटरनेट को फिर से कनेक्ट करते हैंlookup
वापस लौटा दिया है यह अभी भी अवधि के लिए शून्य हो जाएगा। कैश, जो कुछ मिनट हो सकता है, भले ही आपके पास अभी इंटरनेट हो।
TL; DR: lookup
कुछ लौटाना जरूरी नहीं है कि आपके पास इंटरनेट है, और यह कुछ भी वापस नहीं करता है जरूरी नहीं कि आपके पास इंटरनेट नहीं है। यह विश्वसनीय नहीं है।
मैंने data_connection_checker
प्लगइन से प्रेरणा लेकर निम्नलिखित समाधान लागू किया है :
Future<bool> _checkInternetAccess() {
final List<InternetAddress> dnss = [
InternetAddress('8.8.8.8', type: InternetAddressType.IPv4),
InternetAddress('2001:4860:4860::8888', type: InternetAddressType.IPv6),
InternetAddress('1.1.1.1', type: InternetAddressType.IPv4),
InternetAddress('2606:4700:4700::1111', type: InternetAddressType.IPv6),
InternetAddress('208.67.222.222', type: InternetAddressType.IPv4),
InternetAddress('2620:0:ccc::2', type: InternetAddressType.IPv6),
InternetAddress('180.76.76.76', type: InternetAddressType.IPv4),
InternetAddress('2400:da00::6666', type: InternetAddressType.IPv6),
];
final Completer<bool> completer = Completer<bool>();
int callsReturned = 0;
void onCallReturned(bool isAlive) {
if (completer.isCompleted) return;
if (isAlive) {
completer.complete(true);
} else {
callsReturned++;
if (callsReturned >= dnss.length) {
completer.complete(false);
}
}
}
dnss.forEach((dns) => _pingDns(dns).then(onCallReturned));
return completer.future;
}
Future<bool> _pingDns(InternetAddress dnsAddress) async {
const int dnsPort = 53;
const Duration timeout = Duration(seconds: 3);
Socket socket;
try {
socket = await Socket.connect(dnsAddress, dnsPort, timeout: timeout);
socket?.destroy();
return true;
} on SocketException {
socket?.destroy();
}
return false;
}
पूरा करने _checkInternetAccess
के timeout
लिए कॉल की अवधि पूरी होने में (यहाँ पर 3 सेकंड), और अगर हम किसी भी DNS तक पहुँच सकते हैं तो यह पहले जैसे ही पूरा हो जाएगा, दूसरों की प्रतीक्षा किए बिना (जैसा कि एक तक पहुँचने के लिए पर्याप्त है) पता है आपके पास इंटरनेट है)। सभी को फोन किया_pingDns
समानांतर में किए जाते हैं।
यह IPV4 नेटवर्क पर अच्छी तरह से काम करता है, और जब मैं इसे IPV6 नेटवर्क पर परीक्षण नहीं कर सकता (मुझे एक तक पहुंच नहीं है) मुझे लगता है कि इसे अभी भी काम करना चाहिए। यह रिलीज़ मोड बिल्ड पर भी काम करता है, लेकिन मुझे अभी भी ऐप्पल को अपना ऐप सबमिट करना है ताकि यह देखा जा सके कि उन्हें इस समाधान के साथ कोई समस्या मिलती है या नहीं।
यह अधिकांश देशों (चीन सहित) में भी काम करना चाहिए, यदि यह एक में काम नहीं करता है तो आप एक डीएनएस को उस सूची में जोड़ सकते हैं जो आपके लक्षित देश से सुलभ है।