scan method

  1. @override
Future<List<DiscoveredDome>> scan({
  1. Duration timeout = const Duration(seconds: 3),
})
override

One scan.

Implementation

@override
Future<List<DiscoveredDome>> scan({
  Duration timeout = const Duration(seconds: 3),
}) async {
  final client = clientFactory();
  try {
    await client.start();
  } on SocketException {
    // Multicast not available (sandbox, client isolation): nothing found rather than an error (02f ยง17).
    return const [];
  }
  final found = <String, DiscoveredDome>{};
  try {
    final ptrs = await client
        .lookup<PtrResourceRecord>(
          ResourceRecordQuery.serverPointer(freedomeMdnsService),
          timeout: timeout,
        )
        .map((p) => p.domainName)
        .toSet();
    for (final name in ptrs) {
      final srv = await client
          .lookup<SrvResourceRecord>(
            ResourceRecordQuery.service(name),
            timeout: timeout,
          )
          .firstWhere((_) => true, orElse: () => _noSrv);
      if (identical(srv, _noSrv)) continue;
      final txtRecords = await client
          .lookup<TxtResourceRecord>(
            ResourceRecordQuery.text(name),
            timeout: timeout,
          )
          .toList();
      final txt = <String, String>{};
      for (final r in txtRecords) {
        for (final line in r.text.split('\n')) {
          final i = line.indexOf('=');
          if (i > 0) txt[line.substring(0, i)] = line.substring(i + 1);
        }
      }
      final addrs = await client
          .lookup<IPAddressResourceRecord>(
            ResourceRecordQuery.addressIPv4(srv.target),
            timeout: timeout,
          )
          .toList();
      final host = addrs.isNotEmpty
          ? addrs.first.address.address
          : srv.target;
      final d = DiscoveredDome.fromTxt(
        txt,
        host: host,
        port: srv.port,
        seen: clock.now(),
      );
      if (d != null) found[d.id] = d;
    }
  } finally {
    client.stop();
  }
  return found.values.toList();
}