point-source / dart_ping

Multi-platform network ping utility for Dart
31 stars 14 forks source link

DartPingIOS.register(); not working inside secondary isolate #48

Open git-elliot opened 1 year ago

git-elliot commented 1 year ago

I have a use case, where I need to run ping inside another isolate and return results to the main isolate. However when trying to register on ios I get an error.

VERBOSE-2:dart_isolate.cc(1098)] Unhandled exception:
Bad state: The BackgroundIsolateBinaryMessenger.instance value is invalid until BackgroundIsolateBinaryMessenger.ensureInitialized is executed.
#0      BackgroundIsolateBinaryMessenger.instance (package:flutter/src/services/_background_isolate_binary_messenger_io.dart:27:7)
#1      _findBinaryMessenger (package:flutter/src/services/platform_channel.dart:135:42)
#2      EventChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:629:27)
#3      EventChannel.receiveBroadcastStream.<anonymous closure> (package:flutter/src/services/platform_channel.dart:649:7)
#4      _runGuarded (dart:async/stream_controller.dart:814:24)
#5      _BroadcastStreamController._subscribe (dart:async/broadcast_stream_controller.dart:207:7)
#6      _ControllerStream._createSubscription (dart:async/stream_controller.dart:827:19)
#7      _StreamImpl.listen (dart:async/stream_impl.dart:471:9)
#8      new _SinkTransformerStreamSubscription (dart:async/stre<…>
point-source commented 1 year ago

Oh fascinating! I certainly hadn't considered this case. I'll look into it. Thanks for the report

point-source commented 1 year ago

Did you try what was suggested here? If so, what was the outcome?

git-elliot commented 1 year ago

@point-source As mentioned in the comments to the answer Null check operator used on a null value

I already tried initialising BackgroundIsolateBinaryMessenger by passing token from root isolate and hence got this error.

VERBOSE-2:dart_isolate.cc(1098)] Unhandled exception:
Unsupported operation: Background isolates do not support setMessageHandler(). Messages from the host platform always go to the root isolate.
#0      BackgroundIsolateBinaryMessenger.setMessageHandler (package:flutter/src/services/_background_isolate_binary_messenger_io.dart:94:5)
#1      EventChannel.receiveBroadcastStream.<anonymous closure> (package:flutter/src/services/platform_channel.dart:649:23)
#2      _runGuarded (dart:async/stream_controller.dart:814:24)
#3      _BroadcastStreamController._subscribe (dart:async/broadcast_stream_controller.dart:207:7)
#4      _ControllerStream._createSubscription (dart:async/stream_controller.dart:827:19)
#5      _StreamImpl.listen (dart:async/stream_impl.dart:471:9)
#6      new _SinkTransformerStreamSubscription (dart:async/stream_transformers.dart:49:16)
#7      _BoundSinkStream.listen (dart:async/stream_transformers.dart:171:9)
#8      PingiOS.onListen (package:flutter_icmp_ping/src/ping_ios.dart:26:1<…>
point-source commented 1 year ago

After looking into this, it appears to be an issue with the upstream flutter_icmp_ping library which this library depends on for iOS support.

I looked into adding support to that library for this use-case and found that it is currently blocked by this flutter issue.

The only workaround that I am aware of is to use dart:ffi under the hood of flutter_icmp_ping instead of using flutter platform channels. In fact, this might be worth doing regardless but as I am not the author of that library, I have opened this ticket for you.