discoverHosts method
Client searches for AP hosts (Servers). The Client joins a multicast group to listens for advertisements. This method returns boolean future that indicates if the client was able to join the multicast group.
precondition
is an optional Check you can specify the Client to make
before continuing. This is useful if there is some long running task that
must be satisfied before the client begins host discovery. precondition
,
if specified must return a boolean value. On some hosts, you may need to
prepare the system to intercept any messages from the multicast group which
is an example of how the optional parameter can be used to handle such requirement
Implementation
Future<bool> discoverHosts([Future<bool> precondition]) async{
if( precondition != null && !await precondition )
return false;
// Disconnect just in case we were previously connected to one.
await _disconnectFromMulticastGroup();
if( !await _multicastConnect(_multicastPort) )
return false;
// Go through all the interfaces and try to join the multicast group for
// that interface
for(NetworkInterface interface in await interfaces) {
try {
_multicastSocket.joinMulticast(InternetAddress(_multicastGroupIP), interface);
}
catch(ignored){}
}
_multicastSocket.listen((event) {
if (event == RawSocketEvent.read) {
Datagram datagram = _multicastSocket.receive();
if (datagram != null && Packet.from(datagram.data).as<String>().startsWith("PING")) {
// send the name of the host along side the response
_multicastSocket.send(
Packet.from("PONG|$name").bytes,
datagram.address,
datagram.port,
);
List<String> parts = Packet.from(datagram.data).as<String>().split("|");
Device device = new Device.from(
ip: datagram.address.address,
port: int.tryParse(parts[2]),
name: parts[1]
);
if( !_discoveredDevices.contains(device) ){
_discoveredDevices.add(device);
_discoveryListener?.onDiscovery(device, _discoveredDevices);
}
}
else if( datagram != null ){
_discoveryListener?.onAdvertisement(
Device(datagram.address.address, datagram.port),
Packet.fromBytes(datagram.data)
);
}
}
}, onDone: () async{
await _disconnectFromMulticastGroup();
_discoveryListener?.onClose(false, null, null);
}, onError: (Object error, StackTrace stackTrace) async{
await _disconnectFromMulticastGroup();
_discoveryListener?.onClose(true, error, stackTrace);
}, cancelOnError: true);
return true;
}