runSpeedTest method

Future<SpeedTestResult> runSpeedTest({
  1. String downloadUrl = 'https://speed.cloudflare.com/__down?bytes=25000000',
  2. String? uploadUrl,
  3. Duration timeout = const Duration(seconds: 30),
  4. Duration maxDuration = const Duration(seconds: 10),
  5. Duration pingTimeout = const Duration(seconds: 3),
  6. int uploadPayloadBytes = 1048576,
  7. String? pingHost,
  8. int pingCount = 4,
  9. bool includeUpload = true,
  10. bool includePing = true,
  11. void onProgress(
    1. SpeedTestProgress progress
    )?,
})

执行一次网速测试 / Runs a complete speed test.

downloadUrl / uploadUrl 覆盖默认的测速端点; maxDuration 限制单个阶段的采样时长;uploadPayloadBytes 控制上传负载大小; includePingtrue 时先做一次延迟测试并写入 SpeedTestResult.ping / downloadUrl and uploadUrl override the default endpoints, maxDuration caps the sampling window of each phase, uploadPayloadBytes sets the upload payload size, and includePing prefixes the run with a latency test.

Implementation

Future<SpeedTestResult> runSpeedTest({
  String downloadUrl = 'https://speed.cloudflare.com/__down?bytes=25000000',
  String? uploadUrl,
  Duration timeout = const Duration(seconds: 30),
  Duration maxDuration = const Duration(seconds: 10),
  Duration pingTimeout = const Duration(seconds: 3),
  int uploadPayloadBytes = 1048576,
  String? pingHost,
  int pingCount = 4,
  bool includeUpload = true,
  bool includePing = true,
  void Function(SpeedTestProgress progress)? onProgress,
}) async {
  final client = _client ?? http.Client();
  final downloadUri = Uri.parse(downloadUrl);
  final uploadUri = uploadUrl == null ? null : Uri.parse(uploadUrl);

  PingResult? pingResult;
  if (includePing) {
    pingResult = await _pingService.ping(
      host: pingHost ?? downloadUri.host,
      count: pingCount,
      timeout: pingTimeout,
    );
  }

  try {
    final download = await _measureDownload(
      client,
      downloadUri,
      timeout: timeout,
      maxDuration: maxDuration,
      onProgress: onProgress,
    );

    _TransferOutcome? upload;
    if (includeUpload && uploadUri != null) {
      upload = await _measureUpload(
        client,
        uploadUri,
        payload: _buildPayload(uploadPayloadBytes),
        timeout: timeout,
        onProgress: onProgress,
      );
    }

    onProgress?.call(
      const SpeedTestProgress(
        phase: SpeedTestPhase.completed,
        bytes: 0,
        elapsed: Duration.zero,
        speedMbps: 0,
      ),
    );

    return SpeedTestResult(
      downloadSpeed: SpeedTestResult.mbpsFromBytes(
        download.bytes,
        download.elapsed,
      ),
      uploadSpeed: upload == null
          ? 0
          : SpeedTestResult.mbpsFromBytes(upload.bytes, upload.elapsed),
      ping: pingResult?.averageTime ?? 0,
      jitter: pingResult?.jitter ?? 0,
      packetLoss: pingResult?.packetLoss ?? 0,
      downloadedBytes: download.bytes,
      uploadedBytes: upload?.bytes ?? 0,
      downloadDuration: download.elapsed,
      uploadDuration: upload?.elapsed ?? Duration.zero,
      server: downloadUri.host,
      timestamp: DateTime.now(),
    );
  } finally {
    if (_client == null) client.close();
  }
}