প্রস্তাবিত সমাধানগুলির সাথে আমার একটি সমস্যা ছিল, ব্যবহারটি lookupসর্বদা প্রত্যাশিত মানটি ফেরায় না।
এটি ডিএনএস ক্যাশিংয়ের কারণে, কলটির মানটি ক্যাশ করা হয় এবং পরের বার চেষ্টা করে সঠিক কল করার ইন্টেড এটি ক্যাশেড মানটি দেয়। অবশ্যই এটি এখানে একটি ইস্যু হিসাবে এর অর্থ এটি যদি আপনি সংযোগ হারাতে এবং কল করে lookupএটি আপনার কাছে থাকা ক্যাশেড মানটি আবারও ফিরিয়ে দিতে পারে যেমন আপনার ইন্টারনেট রয়েছে এবং বিপরীতে, যদি আপনি lookupফিরে এসে শূন্যের পরে আপনার ইন্টারনেট পুনরায় সংযোগ করেন তবে এটি এখনও সময়কালের জন্য বাতিল হয়ে যাবে ক্যাশে, যা আপনার কাছে এখন ইন্টারনেট থাকলেও কয়েক মিনিট সময় নিতে পারে।
টিএল; ডিআর: 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 সেকেন্ড), এবং আমরা যদি ডিএনএসের কোনওটিতে পৌঁছতে পারি তবে এটি অন্যটির জন্য অপেক্ষা না করেই প্রথমটি পৌঁছানোর সাথে সাথেই এটি সম্পূর্ণ হয়ে যায় (যতক্ষণ না একজনের কাছে পৌঁছানো যথেষ্ট) জেনে নিন আপনার কাছে ইন্টারনেট আছে)। সমস্ত কল _pingDnsসমান্তরালভাবে করা হয়।
এটি একটি আইপিভি 4 নেটওয়ার্কে ভাল কাজ করছে বলে মনে হচ্ছে এবং যখন আমি এটি কোনও আইপিভি 6 নেটওয়ার্কে পরীক্ষা করতে পারি না (আমার একটিতে অ্যাক্সেস নেই) আমি মনে করি এটি এখনও কাজ করা উচিত। এটি রিলিজ মোড বিল্ডগুলিতেও কাজ করে, তবে তারা এখনও এই সমাধান সহ কোনও সমস্যা খুঁজে পান কিনা তা জানতে আমার অ্যাপ্লিকেশনটি অ্যাপলের কাছে জমা দিতে হয়েছিল।
এটি বেশিরভাগ দেশগুলিতেও (চীন সহ) কাজ করা উচিত, যদি এটি একটিতে কাজ না করে তবে আপনি আপনার লক্ষ্যযুক্ত দেশ থেকে অ্যাক্সেসযোগ্য তালিকায় একটি ডিএনএস যুক্ত করতে পারেন।