start method

Future<DeviceManager> start({
  1. dynamic reusePort = false,
})

Implementation

Future<DeviceManager> start({reusePort = false}) async {
  stop();
  _deviceManager?.devices.close();
  final dm = DeviceManager();
  _deviceManager = dm;
  _socket_server = await RawDatagramSocket.bind(
      InternetAddress.anyIPv4, UPNP_PORT,
      reusePort: reusePort);
  // https://github.com/dart-lang/sdk/issues/42250 截止到 dart 2.13.4 仍存在问题,期待新版修复
  // 修复IOS joinMulticast 的问题
  if (Platform.isIOS) {
    final List<NetworkInterface> interfaces = await NetworkInterface.list(
      includeLinkLocal: false,
      type: InternetAddress.anyIPv4.type,
      includeLoopback: false,
    );
    for (final interface in interfaces) {
      final value = Uint8List.fromList(
          UPNP_AddressIPv4.rawAddress + interface.addresses[0].rawAddress);
      _socket_server!.setRawOption(
          RawSocketOption(RawSocketOption.levelIPv4, 12, value));
    }
  } else {
    _socket_server!.joinMulticast(UPNP_AddressIPv4);
  }
  final r = Random();
  final socket_client =
      await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
  _sender = Timer.periodic(Duration(seconds: 3), (Timer t) async {
    final n = r.nextDouble();
    var st = "ssdp:all";
    if (n > 0.3) {
      if (n > 0.6) {
        st = "urn:schemas-upnp-org:service:AVTransport:1";
      } else {
        st = "urn:schemas-upnp-org:device:MediaRenderer:1";
      }
    }
    String msg = 'M-SEARCH * HTTP/1.1\r\n' +
        'ST: $st\r\n' +
        'HOST: 239.255.255.250:1900\r\n' +
        'MX: 3\r\n' +
        'MAN: \"ssdp:discover\"\r\n\r\n';
    socket_client.send(msg.codeUnits, UPNP_AddressIPv4, UPNP_PORT);
    final replay = socket_client.receive();
    if (replay == null) {
      return;
    }
    try {
      String message = String.fromCharCodes(replay.data).trim();
      await dm.onMessage(message);
    } catch (e) {
      print(e);
    }
  });
  _receiver = Timer.periodic(Duration(seconds: 2), (Timer t) async {
    final d = _socket_server!.receive();
    if (d == null) {
      return;
    }
    String message = String.fromCharCodes(d.data).trim();
    // print('Datagram from ${d.address.address}:${d.port}: ${message}');
    try {
      await dm.onMessage(message);
    } catch (e) {
      print(e);
    }
  });
  return dm;
}