| .. | .. |
|---|
| 228 | 228 | final subnet = '${parts[0]}.${parts[1]}.${parts[2]}'; |
|---|
| 229 | 229 | _mqttLog('MQTT: scanning $subnet.0/24 on ${iface.name}'); |
|---|
| 230 | 230 | |
|---|
| 231 | | - // Probe all hosts in parallel — 1s timeout each, runs concurrently |
|---|
| 232 | | - final futures = <Future<String?>>[]; |
|---|
| 233 | | - for (int i = 1; i <= 254; i++) { |
|---|
| 234 | | - final probe = '$subnet.$i'; |
|---|
| 235 | | - if (probe == addr.address) continue; // skip self |
|---|
| 236 | | - futures.add(_probeHost(probe, config.port)); |
|---|
| 237 | | - } |
|---|
| 238 | | - |
|---|
| 239 | | - final results = await Future.wait(futures); |
|---|
| 240 | | - final found = results.firstWhere((r) => r != null, orElse: () => null); |
|---|
| 241 | | - if (found != null) { |
|---|
| 242 | | - _mqttLog('MQTT: subnet scan found broker at $found'); |
|---|
| 243 | | - return found; |
|---|
| 231 | + // Probe in batches of 20 to avoid flooding the network. |
|---|
| 232 | + // Early exit on first hit. |
|---|
| 233 | + for (int batch = 1; batch <= 254; batch += 20) { |
|---|
| 234 | + final end = (batch + 19).clamp(1, 254); |
|---|
| 235 | + final futures = <Future<String?>>[]; |
|---|
| 236 | + for (int i = batch; i <= end; i++) { |
|---|
| 237 | + final probe = '$subnet.$i'; |
|---|
| 238 | + if (probe == addr.address) continue; |
|---|
| 239 | + futures.add(_probeHost(probe, config.port)); |
|---|
| 240 | + } |
|---|
| 241 | + final results = await Future.wait(futures); |
|---|
| 242 | + final found = results.firstWhere((r) => r != null, orElse: () => null); |
|---|
| 243 | + if (found != null) { |
|---|
| 244 | + _mqttLog('MQTT: subnet scan found broker at $found'); |
|---|
| 245 | + return found; |
|---|
| 246 | + } |
|---|
| 244 | 247 | } |
|---|
| 245 | 248 | } |
|---|
| 246 | 249 | } |
|---|