onNodeChanges property
override
Emits the full node list on any change (node joined, left, went on/off-line, tags or DNS name changed).
Saves callers from polling nodes on a timer. Derived from
the same IPN bus NotifyInitialNetMap subscription as
onStateChange; subscribers get the current node inventory as
the first emission, then one emission per inventory change.
Implementation
@override
Stream<List<TailscaleNode>> get onNodeChanges =>
Stream<List<TailscaleNode>>.multi((controller) {
var canceled = false;
List<TailscaleNode>? lastEmitted;
void emitIfChanged(List<TailscaleNode> nodes) {
if (_sameNodes(lastEmitted, nodes)) return;
lastEmitted = nodes;
controller.add(nodes);
}
final subscription = _nodesController.stream.listen(
emitIfChanged,
onError: controller.addError,
onDone: controller.close,
);
unawaited(() async {
try {
final snapshot = _latestNodes ?? await _snapshotNodes();
if (!canceled) {
emitIfChanged(snapshot);
}
} catch (error, stackTrace) {
if (!canceled) {
controller.addError(error, stackTrace);
}
}
}());
controller.onCancel = () {
canceled = true;
return subscription.cancel();
};
}, isBroadcast: true);