A pure Dart utility library that checks for an internet connection by opening a socket to a list of specified addresses, each with individual port and timeout. Defaults are provided for convenience.

Overview

data_connection_checker

Pub

A pure Dart utility library that checks for an internet connection by opening a socket to a list of specified addresses, each with individual port and timeout. Defaults are provided for convenience.

Note that this plugin is in beta and may still have a few issues. Feedback is welcome.

Table of contents

Description

Checks for an internet (data) connection, by opening a socket to a list of addresses.

The defaults of the plugin should be sufficient to reliably determine if the device is currently connected to the global network, e.i. has access to the Internet.

Note that you should not be using the current network status for deciding whether you can reliably make a network connection. Always guard your app code against timeouts and errors that might come from the network layer.

Quick start

DataConnectionChecker() is actually a Singleton. Calling DataConnectionChecker() is guaranteed to always return the same instance.

You can supply a new list to DataConnectionChecker().addresses if you need to check different destinations, ports and timeouts. Also, each address can have its own port and timeout. See InternetAddressCheckOptions in the docs for more info.

First you need to install it (this is the preferred way)

Then you can start using the library:

bool result = await DataConnectionChecker().hasConnection;
if(result == true) {
  print('YAY! Free cute dog pics!');
} else {
  print('No internet :( Reason:');
  print(DataConnectionChecker().lastTryResults);
}

Purpose

The reason this package exists is that connectivity package cannot reliably determine if a data connection is actually available. More info on its page here: https://pub.dev/packages/connectivity

More info on the issue in general:

You can use this package in combination with connectivity in the following way:

var isDeviceConnected = false;

var subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) async {
  if(result != ConnectivityResult.none) {
    isDeviceConnected = await DataConnectionChecker().hasConnection;
  }
});

Note: remember to properly cancel the subscription when it's no longer needed. See connectivity package docs for more info.

How it works

All addresses are pinged simultaneously. On successful result (socket connection to address/port succeeds) a true boolean is pushed to a list, on failure (usually on timeout, default 10 sec) a false boolean is pushed to the same list.

When all the requests complete with either success or failure, a check is made to see if the list contains at least one true boolean. If it does, then an external address is available, so we have data connection. If all the values in this list are false, then we have no connection to the outside world of cute cat and dog pictures, so hasConnection also returns false too.

This all happens at the same time for all addresses, so the maximum waiting time is the address with the highest specified timeout, in case it's unreachable.

I believe this is a reliable and fast method to check if a data connection is available to a device, but I may be wrong. I suggest you open an issue on the Github repository page if you have a better way of.

Defaults

The defaults are based on data collected from https://perfops.net/, https://www.dnsperf.com/#!dns-resolvers

Here's some more info about the defaults:

DEFAULT_ADDRESSES

... includes the top 3 globally available free DNS resolvers.

Address Provider Info
1.1.1.1 CloudFlare https://1.1.1.1
1.0.0.1 CloudFlare https://1.1.1.1
8.8.8.8 Google https://developers.google.com/speed/public-dns/
8.8.4.4 Google https://developers.google.com/speed/public-dns/
208.67.222.222 OpenDNS https://use.opendns.com/
208.67.220.220 OpenDNS https://use.opendns.com/
static final List<AddressCheckOptions> DEFAULT_ADDRESSES = List.unmodifiable([
  AddressCheckOptions(
    InternetAddress('1.1.1.1'),
    port: DEFAULT_PORT,
    timeout: DEFAULT_TIMEOUT,
  ),
  AddressCheckOptions(
    InternetAddress('8.8.4.4'),
    port: DEFAULT_PORT,
    timeout: DEFAULT_TIMEOUT,
  ),
  AddressCheckOptions(
    InternetAddress('208.67.222.222'),
    port: DEFAULT_PORT,
    timeout: DEFAULT_TIMEOUT,
  ),
]);

DEFAULT_PORT

... is 53.

A DNS server listens for requests on port 53 (both UDP and TCP). So all DNS requests are sent to port 53 ...

More info:

static const int DEFAULT_PORT = 53;

DEFAULT_TIMEOUT

... is 10 seconds.

static const Duration DEFAULT_TIMEOUT = Duration(seconds: 10);

DEFAULT_INTERVAL

... is 10 seconds. Interval is the time between automatic checks. Automatic checks start if there's a listener attached to onStatusChange, thus remember to cancel unneeded subscriptions.

checkInterval (which controls how often a check is made) defaults to this value. You can change it if you need to perform checks more often or otherwise.

static const Duration DEFAULT_INTERVAL = const Duration(seconds: 10);
...
Duration checkInterval = DEFAULT_INTERVAL;

Usage

Example:

import 'package:data_connection_checker/data_connection_checker.dart';

main() async {
  // Simple check to see if we have internet
  print("The statement 'this machine is connected to the Internet' is: ");
  print(await DataConnectionChecker().hasConnection);
  // returns a bool

  // We can also get an enum value instead of a bool
  print("Current status: ${await DataConnectionChecker().connectionStatus}");
  // prints either DataConnectionStatus.connected
  // or DataConnectionStatus.disconnected

  // This returns the last results from the last call
  // to either hasConnection or connectionStatus
  print("Last results: ${DataConnectionChecker().lastTryResults}");

  // actively listen for status updates
  // this will cause DataConnectionChecker to check periodically
  // with the interval specified in DataConnectionChecker().checkInterval
  // until listener.cancel() is called
  var listener = DataConnectionChecker().onStatusChange.listen((status) {
    switch (status) {
      case DataConnectionStatus.connected:
        print('Data connection is available.');
        break;
      case DataConnectionStatus.disconnected:
        print('You are disconnected from the internet.');
        break;
    }
  });

  // close listener after 30 seconds, so the program doesn't run forever
  await Future.delayed(Duration(seconds: 30));
  await listener.cancel();
}

Note: Remember to dispose of any listeners, when they're not needed to prevent memory leaks, e.g. in a StatefulWidget's dispose() method:

...
@override
void dispose() {
  listener.cancel();
  super.dispose();
}
...

See example folder for more examples.

License

MIT

Copyright 2019 Kristiyan Mitev and Spirit Navigator

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Features and bugs

Please file feature requests and bugs at the issue tracker.

Comments
  • Migrated Package To Null-Safety along with Code Separation

    Migrated Package To Null-Safety along with Code Separation

    • [x] ✨ Migrated Package To Null-Safety
    • [x] 🧹 Added Separation for Code Readability(code refactor)
    • [x] 🎸 Added universal_io package for web support(chore)
    opened by RounakTadvi 6
  • It's still returning true even if my wifi has not active internet connection..

    It's still returning true even if my wifi has not active internet connection..

    It's still returning true even if my wifi has not active internet connection..

    bool result = await DataConnectionChecker().hasConnection; if(result == true) { print('YAY! Free cute dog pics!'); } else { print('No internet :( Reason:'); print(DataConnectionChecker().lastTryResults); }

    opened by Zeeshan0201 1
  • web support

    web support

    I see the error below when targeting web. Not sure if this is just a limitation of flutter for web at this point or a problem with this library.

    errors.dart:145 Uncaught (in promise) Error: Unsupported operation: InternetAddress
        at Object.throw_ [as throw] (errors.dart:191)
        at Function.new (io_patch.dart:408)
        at get DEFAULT_ADDRESSES (data_connection_checker.dart:61)
        at Function.desc.get [as DEFAULT_ADDRESSES] (utils.dart:75)
        at new data_connection_checker.DataConnectionChecker.__ (data_connection_checker.dart:89)
        at get _instance (data_connection_checker.dart:109)
        at Function.desc.get [as _instance] (utils.dart:75)
        at Function.new (data_connection_checker.dart:93)
        at network_info.NetworkInfoImpl.new._checkConnection (network_info.dart:39)
        at _checkConnection.next (<anonymous>)
        at runBody (async_patch.dart:84)
        at Object._async [as async] (async_patch.dart:123)
        at network_info.NetworkInfoImpl.new.[_checkConnection] (network_info.dart:38)
        at new network_info.NetworkInfoImpl.new (network_info.dart:16)
        at main$ (main.dart:62)
        at main$.next (<anonymous>)
        at onValue (async_patch.dart:45)
        at _RootZone.runUnary (zone.dart:1379)
        at _FutureListener.thenAwait.handleValue (future_impl.dart:137)
        at handleValueCallback (future_impl.dart:678)
        at Function._propagateToListeners (future_impl.dart:707)
        at _Future.new.[_completeWithValue] (future_impl.dart:522)
        at future.dart:400
        at _RootZone.runUnary (zone.dart:1379)
        at _FutureListener.then.handleValue (future_impl.dart:137)
        at handleValueCallback (future_impl.dart:678)
        at Function._propagateToListeners (future_impl.dart:707)
        at _Future.new.[_completeWithValue] (future_impl.dart:522)
        at async._AsyncCallbackEntry.new.callback (future_impl.dart:552)
        at Object._microtaskLoop (schedule_microtask.dart:41)
        at _startMicrotaskLoop (schedule_microtask.dart:50)
        at async_patch.dart:166
    

    Also seeing warnings during build:

    Skipping compiling my_proj|lib/main_web_entrypoint.dart with ddc because some of its
    transitive libraries have sdk dependencies that not supported on this platform:
    
    data_connection_checker|lib/data_connection_checker.dart
    
    opened by rosstimothy 1
  • SocketException connecting to https//1.1.1.1

    SocketException connecting to https//1.1.1.1

    throws SocketException when connecting to https://1.1.1.1 which seem to be down. Exception cannot be handled as it is not bubbled up to the calling function and as a result it causes the app to hang.

    opened by vykes-mac 0
  • Immediately return if any of the requests succeeds

    Immediately return if any of the requests succeeds

    Fixes https://github.com/komapeb/data_connection_checker/issues/23#issue-956018835

    Breaking Changes: I had to change the _lastTryResults variable, it now contains the result of the first successfully completed Future.

    opened by Daplex 1
  • Modify testing logic to immediately return if any of the simultaneous pings succeed

    Modify testing logic to immediately return if any of the simultaneous pings succeed

    Currently the logic is "All addresses are pinged simultaneously. ... When all the requests complete with either success or failure, a check is made to see if the list contains at least one true boolean.". However if any of the hosts slow to respond (for example for some reason CloudFlare DNSes don't respond (https://github.com/komapeb/data_connection_checker/issues/10#issuecomment-736704451) then we have to wait a timeout (10 seconds). In my opinion if any of the pings succeed then the test could already cut short any other pings and return immediately.

    opened by MrCsabaToth 1
Owner
Kristiyan Mitev
I do things. And stuff.
Kristiyan Mitev
Felipe Dias Casseb 2 Feb 9, 2022
Flutter web socket - Flutter Web Socket Example

web_socket_example A new Flutter Web Socket project. Getx and web_scoket_channel

Gizem Malçok 7 Nov 2, 2022
Connection Notifier - A simple way to notify your user about the connection status.

Connection Notifier A simple way to notify your user about the connection status. Basic Usage: ConnectionNotifier class MyApp extends StatelessWidget

haptome 0 Apr 30, 2022
Lightweight internet connection test, lookup a domain.

palestine_connection Lightweight internet connection test, lookup Google domain. Part of PalestineDevelopers project Features Periodic internet connec

Palestine Developers 5 Jun 26, 2022
Dart port of FormCoreJS: A minimal pure functional language based on self dependent types.

FormCore.js port to Dart. So far only the parser and typechecker have been ported i.e. the FormCore.js file in the original repo. (Original readme fro

Modestas Valauskas 2 Jan 28, 2022
A convenience wrapper for building Flutter apps with PDFTron mobile SDK.

About PDFTron Flutter PDFTron's Flutter PDF library brings smooth, flexible, and stand-alone document viewing and editing solutions using Flutter code

PDFTron Systems Inc. 157 Dec 26, 2022
A pragmatic StreamBuilder with sensible defaults

DataStreamBuilder A pragmatic StreamBuilder with sensible defaults. ?? The problem with StreamBuilder StreamBuilder is an essential tool to work with

Flutter Igniter 17 Dec 16, 2021
A powerful Http client for Dart, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.

dio_http A powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, Timeout

null 46 Dec 19, 2021
A powerful Http client for Dart, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.

Language: English | 中文简体 dio A powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File

Flutter中国开源项目 11.2k Jan 3, 2023
Flutter package to create list of radio button, by providing a list of objects it can be a String list or list of Map.

Custom Radio Group List Flutter package to create list of radio button, by providing a list of objects it can be a String list or list of Map. Feature

Ashok Kumar Verma 0 Nov 30, 2021
Custom flutter testing CLI tool for individual test runs and group testing

fluttertest Custom flutter testing CLI tool for inidividual test runs or group testing Overview Flutter is a great framework which has helps developer

vi_mi 15 Nov 6, 2022
Individual Flutter application with BLoC compliance on the theme of the series Rick and Morty

Rick & Morty Catalog REST Individual Flutter application with BLoC compliance on the theme of the series Rick and Morty. List of all characters in the

Maksym Koriak 8 Oct 31, 2022
Socketio dart server and client - Full Socket.io implementation using Dart Lang

Getting Started Step 1: Run dart_server.dart Step 2: Android Emulator has proble

Trần Thiên Trọng 1 Jan 23, 2022
A Flutter widget that checks and displays the version status of application and you can easily guide user to update your app

A most easily usable Flutter widget about application version check! 1. About 1.

Kato Shinya 1 Dec 16, 2021
Flutter package to simplify pagination of list of items from the internet.

PaginationView Installing In your pubspec.yaml dependencies: pagination_view: ^2.0.0-nullsafety.0 import 'package:pagination_view/pagination_view.da

Venkatesh Prasad 151 Dec 29, 2022
Flutter package to simplify pagination of list of items from the internet.

PaginationView Installing In your pubspec.yaml dependencies: pagination_view: ^2.0.0-nullsafety.0 import 'package:pagination_view/pagination_view.da

Venkatesh Prasad 151 Dec 29, 2022
Socket library for creating real-time multiplayer games. Based on TCP, with the ability to send messages over UDP (planned).

Game socket The library was published in early access and is not stable, as it is being developed in parallel with other solutions. English is not a n

Stanislav 10 Aug 10, 2022