From 209151259b50338f7b0e0899d7ae8390004a7342 Mon Sep 17 00:00:00 2001 From: git-elliot Date: Mon, 15 May 2023 22:53:30 +0530 Subject: [PATCH 1/8] Bug fixes and GHA for flutter --- .github/workflows/flutter.yml | 2 +- .github/workflows/publish.yml | 1 - network_tools/example/host_scan.dart | 3 ++- network_tools/lib/src/host_scanner.dart | 1 + network_tools_flutter/lib/src/host_scanner_flutter.dart | 5 +++-- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index c78ff22..6247673 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -3,7 +3,7 @@ # separate terms of service, privacy policy, and support # documentation. -name: Dart +name: Flutter on: push: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d86adfa..bc527bd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,7 +6,6 @@ on: jobs: publish: - runs-on: ubuntu-latest steps: diff --git a/network_tools/example/host_scan.dart b/network_tools/example/host_scan.dart index 1562e8a..837cf49 100644 --- a/network_tools/example/host_scan.dart +++ b/network_tools/example/host_scan.dart @@ -9,6 +9,7 @@ void main() { '${DateFormat.Hms().format(record.time)}: ${record.level.name}: ${record.loggerName}: ${record.message}', ); }); + final log = Logger("host_scan_example"); const String address = '192.168.1.1'; // or You can also get address using network_info_plus package @@ -17,7 +18,7 @@ void main() { // You can set [firstHostId] and scan will start from this host in the network. // Similarly set [lastHostId] and scan will end at this host in the network. - final stream = HostScanner.getAllPingableDevices( + final stream = HostScanner.getAllPingableDevicesAsync( subnet, // firstHostId: 1, // lastHostId: 254, diff --git a/network_tools/lib/src/host_scanner.dart b/network_tools/lib/src/host_scanner.dart index 5c63c70..0a8cb7b 100644 --- a/network_tools/lib/src/host_scanner.dart +++ b/network_tools/lib/src/host_scanner.dart @@ -141,6 +141,7 @@ class HostScanner { ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); activeHostsController.add(message); } else if (message is String && message == 'Done') { + activeHostsController.close(); isolateManager.stop(); } }); diff --git a/network_tools_flutter/lib/src/host_scanner_flutter.dart b/network_tools_flutter/lib/src/host_scanner_flutter.dart index 48f9476..c2a6e8b 100644 --- a/network_tools_flutter/lib/src/host_scanner_flutter.dart +++ b/network_tools_flutter/lib/src/host_scanner_flutter.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:isolate'; import 'dart:math'; -import 'package:dart_ping_ios/dart_ping_ios.dart'; import 'package:network_tools/network_tools.dart'; /// Scans for all hosts in a subnet. @@ -12,6 +11,8 @@ class HostScannerFlutter { /// It won't firstHostId again unless previous scan is completed due to heavy /// resource consumption. /// [resultsInAddressAscendingOrder] = false will return results faster but not in + /// TODO: this should run for ios but currently blocked by + /// https://github.com/point-source/dart_ping/issues/48 static Future> getAllPingableDevices( String subnet, { int firstHostId = HostScanner.defaultFirstHostId, @@ -48,6 +49,7 @@ class HostScannerFlutter { ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); activeHostsController.add(message); } else if (message is String && message == 'Done') { + activeHostsController.close(); isolate.kill(); } }); @@ -58,7 +60,6 @@ class HostScannerFlutter { /// Will search devices in the network inside new isolate // @pragma('vm:entry-point') static Future _startSearchingDevices(SendPort sendPort) async { - DartPingIOS.register(); final port = ReceivePort(); sendPort.send(port.sendPort); From 4d5297d67fae768fb7244cc009f3b2505a7ffa0a Mon Sep 17 00:00:00 2001 From: git-elliot Date: Wed, 30 Aug 2023 10:34:10 +0530 Subject: [PATCH 2/8] trigger validation From 6822a35f6256bd4e675e499a79c418dcf0a65e67 Mon Sep 17 00:00:00 2001 From: git-elliot Date: Wed, 30 Aug 2023 10:35:52 +0530 Subject: [PATCH 3/8] changed branch for flutter project --- .github/workflows/flutter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 6247673..67e1602 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -10,7 +10,7 @@ on: branches: [ "main" ] paths: ['network_tools_flutter/**'] pull_request: - branches: [ "main", "dev" ] + branches: [ "main", "dev-flutter" ] paths: ['network_tools_flutter/**'] concurrency: From f570368af83526eeeeae145dd59c58b4d20ee60e Mon Sep 17 00:00:00 2001 From: git-elliot Date: Wed, 30 Aug 2023 12:17:57 +0530 Subject: [PATCH 4/8] Added Sendable object methods --- network_tools/lib/network_tools.dart | 1 + network_tools/lib/src/host_scanner.dart | 75 +++++++++++-------- network_tools/lib/src/models/active_host.dart | 27 +++++++ .../lib/src/models/sendable_active_host.dart | 7 ++ .../lib/src/host_scanner_flutter.dart | 3 - 5 files changed, 78 insertions(+), 35 deletions(-) create mode 100644 network_tools/lib/src/models/sendable_active_host.dart diff --git a/network_tools/lib/network_tools.dart b/network_tools/lib/network_tools.dart index 60809b5..302378b 100644 --- a/network_tools/lib/network_tools.dart +++ b/network_tools/lib/network_tools.dart @@ -1,3 +1,4 @@ +/// Network tools base library library network_tools; //TODO: add dartdocs diff --git a/network_tools/lib/src/host_scanner.dart b/network_tools/lib/src/host_scanner.dart index 0a8cb7b..c1eb319 100644 --- a/network_tools/lib/src/host_scanner.dart +++ b/network_tools/lib/src/host_scanner.dart @@ -5,6 +5,7 @@ import 'package:dart_ping/dart_ping.dart'; import 'package:isolate_manager/isolate_manager.dart'; import 'package:network_tools/src/models/active_host.dart'; import 'package:network_tools/src/models/callbacks.dart'; +import 'package:network_tools/src/models/sendable_active_host.dart'; import 'package:network_tools/src/network_tools_utils.dart'; import 'package:network_tools/src/port_scanner.dart'; @@ -22,7 +23,7 @@ class HostScanner { /// resource consumption. /// [resultsInAddressAscendingOrder] = false will return results faster but not in /// ascending order and without [progressCallback]. - static Stream getAllPingableDevices( + static Stream _getAllSendablePingableDevices( String subnet, { int firstHostId = defaultFirstHostId, int lastHostId = defaultLastHostId, @@ -32,9 +33,9 @@ class HostScanner { }) async* { final int lastValidSubnet = validateAndGetLastValidSubnet(subnet, firstHostId, lastHostId); - final List> activeHostsFuture = []; - final StreamController activeHostsController = - StreamController(); + final List> activeHostsFuture = []; + final StreamController activeHostsController = + StreamController(); for (int i = firstHostId; i <= lastValidSubnet; i++) { activeHostsFuture.add( @@ -52,9 +53,9 @@ class HostScanner { } int i = 0; - for (final Future host in activeHostsFuture) { + for (final Future host in activeHostsFuture) { i++; - final ActiveHost? tempHost = await host; + final SendableActivateHost? tempHost = await host; progressCallback ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); @@ -66,10 +67,29 @@ class HostScanner { } } - static Future _getHostFromPing({ + static Stream getAllPingableDevices( + String subnet, { + int firstHostId = defaultFirstHostId, + int lastHostId = defaultLastHostId, + int timeoutInSeconds = 1, + ProgressCallback? progressCallback, + bool resultsInAddressAscendingOrder = true, + }) async* { + final stream = _getAllSendablePingableDevices(subnet, firstHostId: firstHostId, lastHostId: lastHostId, + timeoutInSeconds: timeoutInSeconds, progressCallback: progressCallback, resultsInAddressAscendingOrder: resultsInAddressAscendingOrder); + await for (final sendableActivateHost in stream){ + final activeHost = ActiveHost.fromSendableActiveHost(sendableActivateHost: sendableActivateHost); + + await activeHost.resolveInfo(); + + yield activeHost; + } + } + + static Future _getHostFromPing({ required String host, required int i, - required StreamController activeHostsController, + required StreamController activeHostsController, int timeoutInSeconds = 1, }) async { await for (final PingData pingData @@ -78,10 +98,9 @@ class HostScanner { if (response != null) { final Duration? time = response.time; if (time != null) { - final ActiveHost tempActiveHost = - ActiveHost.buildWithAddress(address: host, pingData: pingData); - activeHostsController.add(tempActiveHost); - return tempActiveHost; + final tempSendableActivateHost = SendableActivateHost(host, pingData); + activeHostsController.add(tempSendableActivateHost); + return tempSendableActivateHost; } } } @@ -113,9 +132,7 @@ class HostScanner { int timeoutInSeconds = 1, ProgressCallback? progressCallback, bool resultsInAddressAscendingOrder = true, - }) { - final StreamController activeHostsController = - StreamController(); + }) async* { const int scanRangeForIsolate = 51; final int lastValidSubnet = @@ -134,19 +151,19 @@ class HostScanner { timeoutInSeconds.toString(), resultsInAddressAscendingOrder.toString(), ]); - - isolateManager.onMessage.listen((message) { - if (message is ActiveHost) { + await for (final message in isolateManager.onMessage.asBroadcastStream()){ + if (message is SendableActivateHost) { progressCallback ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); - activeHostsController.add(message); + + final activeHostFound = ActiveHost.fromSendableActiveHost(sendableActivateHost: message); + await activeHostFound.resolveInfo(); + yield activeHostFound; } else if (message is String && message == 'Done') { - activeHostsController.close(); isolateManager.stop(); } - }); + } } - return activeHostsController.stream; } /// Will search devices in the network inside new isolate @@ -169,8 +186,8 @@ class HostScanner { /// Will contain all the hosts that got discovered in the network, will /// be use inorder to cancel on dispose of the page. - final Stream hostsDiscoveredInNetwork = - HostScanner.getAllPingableDevices( + final Stream hostsDiscoveredInNetwork = + HostScanner._getAllSendablePingableDevices( subnetIsolate, firstHostId: firstSubnetIsolate, lastHostId: lastSubnetIsolate, @@ -178,14 +195,8 @@ class HostScanner { resultsInAddressAscendingOrder: resultsInAddressAscendingOrder, ); - await for (final ActiveHost activeHostFound in hostsDiscoveredInNetwork) { - activeHostFound.deviceName.then((value) { - activeHostFound.mdnsInfo.then((value) { - activeHostFound.hostName.then((value) { - channel.sendResult(activeHostFound); - }); - }); - }); + await for (final SendableActivateHost activeHostFound in hostsDiscoveredInNetwork) { + channel.sendResult(activeHostFound); } channel.sendResult('Done'); }); diff --git a/network_tools/lib/src/models/active_host.dart b/network_tools/lib/src/models/active_host.dart index 4c714ed..0bd99ef 100644 --- a/network_tools/lib/src/models/active_host.dart +++ b/network_tools/lib/src/models/active_host.dart @@ -1,6 +1,7 @@ import 'package:dart_ping/dart_ping.dart'; import 'package:network_tools/src/models/mdns_info.dart'; import 'package:network_tools/src/models/open_port.dart'; +import 'package:network_tools/src/models/sendable_active_host.dart'; import 'package:network_tools/src/network_tools_utils.dart'; import 'package:universal_io/io.dart'; @@ -65,6 +66,32 @@ class ActiveHost extends Comparable { ); } + factory ActiveHost.fromSendableActiveHost({ + required SendableActivateHost sendableActivateHost, + List openPorts = const [], + PingData? pingData, + MdnsInfo? mdnsInfo, + }) { + final InternetAddress? internetAddressTemp = + InternetAddress.tryParse(sendableActivateHost.address); + if (internetAddressTemp == null) { + throw 'Cant parse address ${sendableActivateHost.address} to InternetAddress'; + } + return ActiveHost( + internetAddress: internetAddressTemp, + openPorts: openPorts, + pingData: pingData, + mdnsInfoVar: mdnsInfo, + ); + } + + Future resolveInfo() async { + await deviceName; + await mdnsInfo; + await hostName; + } + + static const generic = 'Generic Device'; InternetAddress internetAddress; diff --git a/network_tools/lib/src/models/sendable_active_host.dart b/network_tools/lib/src/models/sendable_active_host.dart new file mode 100644 index 0000000..9069a22 --- /dev/null +++ b/network_tools/lib/src/models/sendable_active_host.dart @@ -0,0 +1,7 @@ +import 'package:dart_ping/dart_ping.dart'; + +class SendableActivateHost{ + SendableActivateHost(this.address, this.pingData); + final String address; + final PingData pingData; +} diff --git a/network_tools_flutter/lib/src/host_scanner_flutter.dart b/network_tools_flutter/lib/src/host_scanner_flutter.dart index c2a6e8b..8744f06 100644 --- a/network_tools_flutter/lib/src/host_scanner_flutter.dart +++ b/network_tools_flutter/lib/src/host_scanner_flutter.dart @@ -11,8 +11,6 @@ class HostScannerFlutter { /// It won't firstHostId again unless previous scan is completed due to heavy /// resource consumption. /// [resultsInAddressAscendingOrder] = false will return results faster but not in - /// TODO: this should run for ios but currently blocked by - /// https://github.com/point-source/dart_ping/issues/48 static Future> getAllPingableDevices( String subnet, { int firstHostId = HostScanner.defaultFirstHostId, @@ -49,7 +47,6 @@ class HostScannerFlutter { ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); activeHostsController.add(message); } else if (message is String && message == 'Done') { - activeHostsController.close(); isolate.kill(); } }); From c404678b2ae193f6e4b481e3fafe74f4b6b6479c Mon Sep 17 00:00:00 2001 From: git-elliot Date: Wed, 30 Aug 2023 12:21:06 +0530 Subject: [PATCH 5/8] removing flutter based files --- network_tools_flutter/lib/src/host_scanner_flutter.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/network_tools_flutter/lib/src/host_scanner_flutter.dart b/network_tools_flutter/lib/src/host_scanner_flutter.dart index 8744f06..48f9476 100644 --- a/network_tools_flutter/lib/src/host_scanner_flutter.dart +++ b/network_tools_flutter/lib/src/host_scanner_flutter.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:isolate'; import 'dart:math'; +import 'package:dart_ping_ios/dart_ping_ios.dart'; import 'package:network_tools/network_tools.dart'; /// Scans for all hosts in a subnet. @@ -57,6 +58,7 @@ class HostScannerFlutter { /// Will search devices in the network inside new isolate // @pragma('vm:entry-point') static Future _startSearchingDevices(SendPort sendPort) async { + DartPingIOS.register(); final port = ReceivePort(); sendPort.send(port.sendPort); From bda2f90911666892f1aa793cdbbd53e0ee1fc00b Mon Sep 17 00:00:00 2001 From: git-elliot Date: Wed, 30 Aug 2023 13:20:58 +0530 Subject: [PATCH 6/8] flutter version of host_scanner --- network_tools/lib/network_tools.dart | 1 + network_tools/lib/src/host_scanner.dart | 46 +++++++++---------- .../lib/src/host_scanner_flutter.dart | 34 ++++++-------- .../test/host_scan_flutter_test.dart | 4 +- 4 files changed, 39 insertions(+), 46 deletions(-) diff --git a/network_tools/lib/network_tools.dart b/network_tools/lib/network_tools.dart index 302378b..345e7a8 100644 --- a/network_tools/lib/network_tools.dart +++ b/network_tools/lib/network_tools.dart @@ -8,4 +8,5 @@ export 'src/models/active_host.dart'; export 'src/models/callbacks.dart'; export 'src/models/mdns_info.dart'; export 'src/models/open_port.dart'; +export 'src/models/sendable_active_host.dart'; export 'src/port_scanner.dart'; diff --git a/network_tools/lib/src/host_scanner.dart b/network_tools/lib/src/host_scanner.dart index c1eb319..ebfcb17 100644 --- a/network_tools/lib/src/host_scanner.dart +++ b/network_tools/lib/src/host_scanner.dart @@ -23,7 +23,26 @@ class HostScanner { /// resource consumption. /// [resultsInAddressAscendingOrder] = false will return results faster but not in /// ascending order and without [progressCallback]. - static Stream _getAllSendablePingableDevices( + static Stream getAllPingableDevices( + String subnet, { + int firstHostId = defaultFirstHostId, + int lastHostId = defaultLastHostId, + int timeoutInSeconds = 1, + ProgressCallback? progressCallback, + bool resultsInAddressAscendingOrder = true, + }) async* { + final stream = getAllSendablePingableDevices(subnet, firstHostId: firstHostId, lastHostId: lastHostId, + timeoutInSeconds: timeoutInSeconds, progressCallback: progressCallback, resultsInAddressAscendingOrder: resultsInAddressAscendingOrder); + await for (final sendableActivateHost in stream){ + final activeHost = ActiveHost.fromSendableActiveHost(sendableActivateHost: sendableActivateHost); + + await activeHost.resolveInfo(); + + yield activeHost; + } + } + + static Stream getAllSendablePingableDevices( String subnet, { int firstHostId = defaultFirstHostId, int lastHostId = defaultLastHostId, @@ -66,27 +85,7 @@ class HostScanner { yield tempHost; } } - - static Stream getAllPingableDevices( - String subnet, { - int firstHostId = defaultFirstHostId, - int lastHostId = defaultLastHostId, - int timeoutInSeconds = 1, - ProgressCallback? progressCallback, - bool resultsInAddressAscendingOrder = true, - }) async* { - final stream = _getAllSendablePingableDevices(subnet, firstHostId: firstHostId, lastHostId: lastHostId, - timeoutInSeconds: timeoutInSeconds, progressCallback: progressCallback, resultsInAddressAscendingOrder: resultsInAddressAscendingOrder); - await for (final sendableActivateHost in stream){ - final activeHost = ActiveHost.fromSendableActiveHost(sendableActivateHost: sendableActivateHost); - - await activeHost.resolveInfo(); - - yield activeHost; - } - } - - static Future _getHostFromPing({ + static Future _getHostFromPing({ required String host, required int i, required StreamController activeHostsController, @@ -107,6 +106,7 @@ class HostScanner { return null; } + static int validateAndGetLastValidSubnet( String subnet, int firstHostId, @@ -187,7 +187,7 @@ class HostScanner { /// Will contain all the hosts that got discovered in the network, will /// be use inorder to cancel on dispose of the page. final Stream hostsDiscoveredInNetwork = - HostScanner._getAllSendablePingableDevices( + HostScanner.getAllSendablePingableDevices( subnetIsolate, firstHostId: firstSubnetIsolate, lastHostId: lastSubnetIsolate, diff --git a/network_tools_flutter/lib/src/host_scanner_flutter.dart b/network_tools_flutter/lib/src/host_scanner_flutter.dart index 48f9476..0bea173 100644 --- a/network_tools_flutter/lib/src/host_scanner_flutter.dart +++ b/network_tools_flutter/lib/src/host_scanner_flutter.dart @@ -12,17 +12,15 @@ class HostScannerFlutter { /// It won't firstHostId again unless previous scan is completed due to heavy /// resource consumption. /// [resultsInAddressAscendingOrder] = false will return results faster but not in - static Future> getAllPingableDevices( + static Stream getAllPingableDevices( String subnet, { int firstHostId = HostScanner.defaultFirstHostId, int lastHostId = HostScanner.defaultLastHostId, int timeoutInSeconds = 1, ProgressCallback? progressCallback, bool resultsInAddressAscendingOrder = true, - }) async { + }) async* { const int scanRangeForIsolate = 51; - final StreamController activeHostsController = - StreamController(); final int lastValidSubnet = HostScanner.validateAndGetLastValidSubnet( subnet, firstHostId, lastHostId); @@ -33,8 +31,7 @@ class HostScannerFlutter { final receivePort = ReceivePort(); final isolate = await Isolate.spawn( HostScannerFlutter._startSearchingDevices, receivePort.sendPort); - - receivePort.listen((message) { + await for (final message in receivePort.asBroadcastStream()){ if (message is SendPort) { message.send([ subnet, @@ -43,20 +40,21 @@ class HostScannerFlutter { timeoutInSeconds.toString(), resultsInAddressAscendingOrder.toString() ]); - } else if (message is ActiveHost) { + } else if (message is SendableActivateHost) { progressCallback ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); - activeHostsController.add(message); + final activeHostFound = ActiveHost.fromSendableActiveHost(sendableActivateHost: message); + await activeHostFound.resolveInfo(); + yield activeHostFound; } else if (message is String && message == 'Done') { isolate.kill(); } - }); + } } - return activeHostsController.stream; } /// Will search devices in the network inside new isolate - // @pragma('vm:entry-point') + @pragma('vm:entry-point') static Future _startSearchingDevices(SendPort sendPort) async { DartPingIOS.register(); final port = ReceivePort(); @@ -71,8 +69,8 @@ class HostScannerFlutter { /// Will contain all the hosts that got discovered in the network, will /// be use inorder to cancel on dispose of the page. - final Stream hostsDiscoveredInNetwork = - HostScanner.getAllPingableDevices( + final Stream hostsDiscoveredInNetwork = + HostScanner.getAllSendablePingableDevices( subnetIsolate, firstHostId: firstSubnetIsolate, lastHostId: lastSubnetIsolate, @@ -80,14 +78,8 @@ class HostScannerFlutter { resultsInAddressAscendingOrder: resultsInAddressAscendingOrder, ); - await for (final ActiveHost activeHostFound in hostsDiscoveredInNetwork) { - activeHostFound.deviceName.then((value) { - activeHostFound.mdnsInfo.then((value) { - activeHostFound.hostName.then((value) { - sendPort.send(activeHostFound); - }); - }); - }); + await for (final SendableActivateHost activeHostFound in hostsDiscoveredInNetwork) { + sendPort.send(activeHostFound); } sendPort.send('Done'); } diff --git a/network_tools_flutter/test/host_scan_flutter_test.dart b/network_tools_flutter/test/host_scan_flutter_test.dart index 66d700a..520b64a 100644 --- a/network_tools_flutter/test/host_scan_flutter_test.dart +++ b/network_tools_flutter/test/host_scan_flutter_test.dart @@ -35,7 +35,7 @@ void main() { test('Running getAllPingableDevicesAsync tests', () async { expectLater( //There should be at least one device pingable in network - await HostScannerFlutter.getAllPingableDevices( + HostScannerFlutter.getAllPingableDevices( interfaceIp, timeoutInSeconds: 3, ), @@ -43,7 +43,7 @@ void main() { ); expectLater( //Should emit at least our own local machine when pinging all hosts. - await HostScannerFlutter.getAllPingableDevices( + HostScannerFlutter.getAllPingableDevices( interfaceIp, timeoutInSeconds: 3, ), From 5c626ee5d4eb00771335571107bbdc6d96ba30f9 Mon Sep 17 00:00:00 2001 From: git-elliot Date: Wed, 30 Aug 2023 13:22:49 +0530 Subject: [PATCH 7/8] fixed analyzer problems --- network_tools/lib/src/host_scanner.dart | 2 +- network_tools/lib/src/port_scanner.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/network_tools/lib/src/host_scanner.dart b/network_tools/lib/src/host_scanner.dart index ebfcb17..d1ff4bf 100644 --- a/network_tools/lib/src/host_scanner.dart +++ b/network_tools/lib/src/host_scanner.dart @@ -32,7 +32,7 @@ class HostScanner { bool resultsInAddressAscendingOrder = true, }) async* { final stream = getAllSendablePingableDevices(subnet, firstHostId: firstHostId, lastHostId: lastHostId, - timeoutInSeconds: timeoutInSeconds, progressCallback: progressCallback, resultsInAddressAscendingOrder: resultsInAddressAscendingOrder); + timeoutInSeconds: timeoutInSeconds, progressCallback: progressCallback, resultsInAddressAscendingOrder: resultsInAddressAscendingOrder,); await for (final sendableActivateHost in stream){ final activeHost = ActiveHost.fromSendableActiveHost(sendableActivateHost: sendableActivateHost); diff --git a/network_tools/lib/src/port_scanner.dart b/network_tools/lib/src/port_scanner.dart index b5bb280..974aab3 100644 --- a/network_tools/lib/src/port_scanner.dart +++ b/network_tools/lib/src/port_scanner.dart @@ -34,7 +34,7 @@ class PortScanner { 443, 989, 990, - 3389 + 3389, ]; /// Checks if the single [port] is open or not for the [target]. From 50685db16f96c35e1d4086c898f1df295722d45b Mon Sep 17 00:00:00 2001 From: git-elliot Date: Wed, 30 Aug 2023 14:42:32 +0530 Subject: [PATCH 8/8] HostScanFlutter is ready --- network_tools/lib/src/host_scanner.dart | 32 ++++++++--------- network_tools/lib/src/models/active_host.dart | 10 +++--- .../lib/src/models/sendable_active_host.dart | 4 +-- .../lib/src/host_scanner_flutter.dart | 36 +++++++++++++------ network_tools_flutter/pubspec.yaml | 3 ++ 5 files changed, 51 insertions(+), 34 deletions(-) diff --git a/network_tools/lib/src/host_scanner.dart b/network_tools/lib/src/host_scanner.dart index d1ff4bf..776d6ef 100644 --- a/network_tools/lib/src/host_scanner.dart +++ b/network_tools/lib/src/host_scanner.dart @@ -33,16 +33,16 @@ class HostScanner { }) async* { final stream = getAllSendablePingableDevices(subnet, firstHostId: firstHostId, lastHostId: lastHostId, timeoutInSeconds: timeoutInSeconds, progressCallback: progressCallback, resultsInAddressAscendingOrder: resultsInAddressAscendingOrder,); - await for (final sendableActivateHost in stream){ - final activeHost = ActiveHost.fromSendableActiveHost(sendableActivateHost: sendableActivateHost); + await for (final sendableActiveHost in stream){ + final activeHost = ActiveHost.fromSendableActiveHost(sendableActiveHost: sendableActiveHost); await activeHost.resolveInfo(); yield activeHost; } } - - static Stream getAllSendablePingableDevices( + /// Same as [getAllPingableDevices] but can be called or run inside isolate. + static Stream getAllSendablePingableDevices( String subnet, { int firstHostId = defaultFirstHostId, int lastHostId = defaultLastHostId, @@ -52,9 +52,9 @@ class HostScanner { }) async* { final int lastValidSubnet = validateAndGetLastValidSubnet(subnet, firstHostId, lastHostId); - final List> activeHostsFuture = []; - final StreamController activeHostsController = - StreamController(); + final List> activeHostsFuture = []; + final StreamController activeHostsController = + StreamController(); for (int i = firstHostId; i <= lastValidSubnet; i++) { activeHostsFuture.add( @@ -72,9 +72,9 @@ class HostScanner { } int i = 0; - for (final Future host in activeHostsFuture) { + for (final Future host in activeHostsFuture) { i++; - final SendableActivateHost? tempHost = await host; + final SendableActiveHost? tempHost = await host; progressCallback ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); @@ -85,10 +85,10 @@ class HostScanner { yield tempHost; } } - static Future _getHostFromPing({ + static Future _getHostFromPing({ required String host, required int i, - required StreamController activeHostsController, + required StreamController activeHostsController, int timeoutInSeconds = 1, }) async { await for (final PingData pingData @@ -97,7 +97,7 @@ class HostScanner { if (response != null) { final Duration? time = response.time; if (time != null) { - final tempSendableActivateHost = SendableActivateHost(host, pingData); + final tempSendableActivateHost = SendableActiveHost(host, pingData); activeHostsController.add(tempSendableActivateHost); return tempSendableActivateHost; } @@ -152,11 +152,11 @@ class HostScanner { resultsInAddressAscendingOrder.toString(), ]); await for (final message in isolateManager.onMessage.asBroadcastStream()){ - if (message is SendableActivateHost) { + if (message is SendableActiveHost) { progressCallback ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); - final activeHostFound = ActiveHost.fromSendableActiveHost(sendableActivateHost: message); + final activeHostFound = ActiveHost.fromSendableActiveHost(sendableActiveHost: message); await activeHostFound.resolveInfo(); yield activeHostFound; } else if (message is String && message == 'Done') { @@ -186,7 +186,7 @@ class HostScanner { /// Will contain all the hosts that got discovered in the network, will /// be use inorder to cancel on dispose of the page. - final Stream hostsDiscoveredInNetwork = + final Stream hostsDiscoveredInNetwork = HostScanner.getAllSendablePingableDevices( subnetIsolate, firstHostId: firstSubnetIsolate, @@ -195,7 +195,7 @@ class HostScanner { resultsInAddressAscendingOrder: resultsInAddressAscendingOrder, ); - await for (final SendableActivateHost activeHostFound in hostsDiscoveredInNetwork) { + await for (final SendableActiveHost activeHostFound in hostsDiscoveredInNetwork) { channel.sendResult(activeHostFound); } channel.sendResult('Done'); diff --git a/network_tools/lib/src/models/active_host.dart b/network_tools/lib/src/models/active_host.dart index 0bd99ef..041153e 100644 --- a/network_tools/lib/src/models/active_host.dart +++ b/network_tools/lib/src/models/active_host.dart @@ -67,20 +67,19 @@ class ActiveHost extends Comparable { } factory ActiveHost.fromSendableActiveHost({ - required SendableActivateHost sendableActivateHost, + required SendableActiveHost sendableActiveHost, List openPorts = const [], - PingData? pingData, MdnsInfo? mdnsInfo, }) { final InternetAddress? internetAddressTemp = - InternetAddress.tryParse(sendableActivateHost.address); + InternetAddress.tryParse(sendableActiveHost.address); if (internetAddressTemp == null) { - throw 'Cant parse address ${sendableActivateHost.address} to InternetAddress'; + throw 'Cant parse address ${sendableActiveHost.address} to InternetAddress'; } return ActiveHost( internetAddress: internetAddressTemp, openPorts: openPorts, - pingData: pingData, + pingData: sendableActiveHost.pingData, mdnsInfoVar: mdnsInfo, ); } @@ -91,7 +90,6 @@ class ActiveHost extends Comparable { await hostName; } - static const generic = 'Generic Device'; InternetAddress internetAddress; diff --git a/network_tools/lib/src/models/sendable_active_host.dart b/network_tools/lib/src/models/sendable_active_host.dart index 9069a22..2be38f5 100644 --- a/network_tools/lib/src/models/sendable_active_host.dart +++ b/network_tools/lib/src/models/sendable_active_host.dart @@ -1,7 +1,7 @@ import 'package:dart_ping/dart_ping.dart'; -class SendableActivateHost{ - SendableActivateHost(this.address, this.pingData); +class SendableActiveHost{ + SendableActiveHost(this.address, this.pingData); final String address; final PingData pingData; } diff --git a/network_tools_flutter/lib/src/host_scanner_flutter.dart b/network_tools_flutter/lib/src/host_scanner_flutter.dart index 0bea173..7cb5685 100644 --- a/network_tools_flutter/lib/src/host_scanner_flutter.dart +++ b/network_tools_flutter/lib/src/host_scanner_flutter.dart @@ -2,8 +2,11 @@ import 'dart:async'; import 'dart:isolate'; import 'dart:math'; +import 'package:dart_ping/dart_ping.dart'; import 'package:dart_ping_ios/dart_ping_ios.dart'; +import 'package:flutter_isolate/flutter_isolate.dart'; import 'package:network_tools/network_tools.dart'; +import 'package:universal_io/io.dart'; /// Scans for all hosts in a subnet. class HostScannerFlutter { @@ -29,9 +32,18 @@ class HostScannerFlutter { i += scanRangeForIsolate + 1) { final limit = min(i + scanRangeForIsolate, lastValidSubnet); final receivePort = ReceivePort(); - final isolate = await Isolate.spawn( - HostScannerFlutter._startSearchingDevices, receivePort.sendPort); - await for (final message in receivePort.asBroadcastStream()){ + dynamic isolate; + + if(Platform.isAndroid || Platform.isIOS){ + // Flutter isolate is not implemented for other platforms than these two + isolate = await FlutterIsolate.spawn( + HostScannerFlutter._startSearchingDevices, receivePort.sendPort); + } else { + isolate = await Isolate.spawn( + HostScannerFlutter._startSearchingDevices, receivePort.sendPort); + } + + await for (final message in receivePort.asBroadcastStream()) { if (message is SendPort) { message.send([ subnet, @@ -40,12 +52,14 @@ class HostScannerFlutter { timeoutInSeconds.toString(), resultsInAddressAscendingOrder.toString() ]); - } else if (message is SendableActivateHost) { + } else if (message is List) { progressCallback ?.call((i - firstHostId) * 100 / (lastValidSubnet - firstHostId)); - final activeHostFound = ActiveHost.fromSendableActiveHost(sendableActivateHost: message); - await activeHostFound.resolveInfo(); - yield activeHostFound; + final activeHostFound = ActiveHost.fromSendableActiveHost( + sendableActiveHost: SendableActiveHost( + message[0], PingData.fromJson(message[1]))); + await activeHostFound.resolveInfo(); + yield activeHostFound; } else if (message is String && message == 'Done') { isolate.kill(); } @@ -69,7 +83,7 @@ class HostScannerFlutter { /// Will contain all the hosts that got discovered in the network, will /// be use inorder to cancel on dispose of the page. - final Stream hostsDiscoveredInNetwork = + final Stream hostsDiscoveredInNetwork = HostScanner.getAllSendablePingableDevices( subnetIsolate, firstHostId: firstSubnetIsolate, @@ -78,8 +92,10 @@ class HostScannerFlutter { resultsInAddressAscendingOrder: resultsInAddressAscendingOrder, ); - await for (final SendableActivateHost activeHostFound in hostsDiscoveredInNetwork) { - sendPort.send(activeHostFound); + await for (final SendableActiveHost activeHostFound + in hostsDiscoveredInNetwork) { + sendPort + .send([activeHostFound.address, activeHostFound.pingData.toJson()]); } sendPort.send('Done'); } diff --git a/network_tools_flutter/pubspec.yaml b/network_tools_flutter/pubspec.yaml index c4fab1f..2753719 100644 --- a/network_tools_flutter/pubspec.yaml +++ b/network_tools_flutter/pubspec.yaml @@ -14,8 +14,11 @@ dependencies: sdk: flutter network_tools: path: ../network_tools + # Multi-platform network ping utility. + dart_ping: ^8.0.1 dart_ping_ios: ^3.0.0 universal_io: ^2.2.0 + flutter_isolate: ^2.0.4 dev_dependencies: flutter_test: