discoverHosts method

Future<bool> discoverHosts (
  1. [Future<bool> precondition]
)

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;
}