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