scan method
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();
}