discover method

Future<StunResponse> discover()

Discovers external IP address and port using the pool of STUN servers

This method tries multiple STUN servers in order of their health score until it gets a successful response or exhausts all servers.

Implementation

Future<StunResponse> discover() async {
  if (_servers.isEmpty) {
    throw Exception('No STUN servers available');
  }

  // Check server health if it hasn't been done yet
  if (_servers.every((s) => s.lastSuccessTime == null)) {
    await _checkServerHealth();
  }

  // Sort servers by health score (highest first)
  _servers.sort((a, b) => b.healthScore.compareTo(a.healthScore));

  // Try servers in order of health score
  Exception? lastException;
  for (final server in _servers) {
    try {
      final stopwatch = Stopwatch()..start();
      final response = await server.client.discover();
      stopwatch.stop();

      // Update server health info on success
      server.lastResponseTime = stopwatch.elapsed;
      server.lastSuccessTime = DateTime.now();
      server.consecutiveFailures = 0;
      server.healthScore = min(100, server.healthScore + 5);

      return response;
    } catch (e) {
      // Update server health info on failure
      server.consecutiveFailures++;
      server.healthScore = max(0, server.healthScore - 10);
      lastException = e is Exception ? e : Exception(e.toString());
    }
  }

  // If we get here, all servers failed
  throw lastException ?? Exception('All STUN servers failed');
}