Flutter Dart Dio Get Request 太慢了

Flutter Dart Dio Get Request is so slow

我在数字海洋中托管 space - 它基本上是数字海洋的 Amazon S3 等价物。我对 dio 的问题是,我正在使用 dio 向 10MB 大小的文件发出获取请求。该请求在我的 phone 上大约需要 9 秒,但在我的浏览器中需要 3 秒。我的自定义后端也有这个问题。使用 dio(使用 dart 的 http 模块)发出的请求似乎非常慢。我需要解决这个问题,因为我需要不时向用户传输 50MB 的数据。为什么 dio 对 GET 请求的响应很慢?

我怀疑这可能是根本原因check here

await Dio().get(
        "Remote_Url_I_can_not_share",
        onReceiveProgress: (int downloaded, int total) {
          listener
              .call((downloaded.toDouble() / total.toDouble() * metadataPerc));
        },
        cancelToken: _cancelToken,
      ).catchError((err) => throw err);

我对 DigitalOcean Spaces 的体验非常不稳定。在我看来,DO Spaces 还没有准备好投入生产。我在网站上使用他们的 CDN 功能,有时响应时间约为 20 毫秒,但有时会超过 6 秒。这是在 AMS3 数据中心区域。

您能否确认其他 S3/servers 也会发生这种情况?例如 gstatic,或 Amazon CloudFront CDN?

这种波动行为不断发生,这就是我们将所有资产转移到 Amazon S3 + CloudFront 的原因。它提供了更加一致的结果。

您正在测试的 phone 可能使用非常未优化的 traceroute 到 DigitalOcean 数据中心。这就是为什么你应该尝试不同的服务器。

我相信这个原因;底层某处的缓冲区大小限制为 8KB。

我试了一整天来增加它。仍然没有成功。让我分享一下我对缓冲区大小的经验。

假设您正在下载一个 16 MB 的文件。

请考虑远程服务器的速度也比您的下载速度快。 (我的意思是忘记服务器负载等。)

如果缓冲区大小:

128 字节,下载 16mb 文件需要:10.820 秒

1024 字节,下载 16mb 文件需要:6.276 秒

8192 字节,下载 16mb 文件需要:4.776 秒

16384 字节,下载 16mb 文件需要:3.759 秒

32768 字节,下载 16mb 文件需要:2.956 秒

-------- 在此之后,如果我们增加块大小,下载时间也会增加

65536 字节,下载 16mb 文件需要:4.186 秒

131072 字节,下载 16mb 文件需要:5.250 秒

524288 字节,下载 16mb 文件需要:7.460 秒

所以不知何故,如果您可以将缓冲区大小设置为 16k 或 32k 而不是 8k,我相信下载速度会提高。

请随时测试您的结果(我进行了 3 次尝试,并在时间上取了它们的平均值)

package dltest;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class DLTest 
{
    public static void main(String[] args) throws Exception 
    {

        String filePath = "http://hcmaslov.d-real.sci-nnov.ru/public/mp3/Metallica/Metallica%20'...And%20Justice%20For%20All'.mp3";

        URL url = new URL(filePath);
        URLConnection uc = url.openConnection();
        InputStream is = uc.getInputStream();

        long start = System.currentTimeMillis();

        int downloaded = 0;
        int total = uc.getContentLength();
        int partialRead = 0;

        // byte chunk[] = new byte[128];
        // byte chunk[] = new byte[1024];
        // byte chunk[] = new byte[4096];
        // byte chunk[] = new byte[8192];
           byte chunk[] = new byte[16384];
        // byte chunk[] = new byte[32768];
        // byte chunk[] = new byte[524288];

        while ( (partialRead = is.read(chunk)) != -1)
        {
                // Print If You Like..
        }

        is.close();
        long end = System.currentTimeMillis();

        System.out.println("Chunk Size ["+(chunk.length)+"] Time To Complete :  "+(end - start));
    }
}