【问题标题】:How to calculate download / upload internet speed in Angular如何在 Angular 中计算下载/上传互联网速度
【发布时间】:2020-07-23 02:27:25
【问题描述】:

我想在 Angular 中计算下载和上传互联网速度。

请求 API 不会是最好的解决方案,因为如果服务器本身因负载变慢,结果将不正确。

也许有针对 Angular 的解决方案,它为此使用特殊站点(例如 speedtest.net)。

有什么想法吗?

【问题讨论】:

  • 你想如何在不启动汽车并测量其速度的情况下测量汽车的速度?
  • 我不明白你的问题,但我想你问的是如何制作一个行为类似于fast.com的Angular App
  • @CryingFreeman 我需要确定用户的慢速连接。

标签: angular


【解决方案1】:

网速是多少?

每个人都希望下载的速度越来越快,上传文件的速度也越来越快。但是这是什么意思?当您下载或上传某些内容时,您和服务器以特定方式进行通信。你们都有互联网连接,但在大多数情况下,您的速度比服务器的连接慢。要理解这一点,只需遵循以下逻辑:

您正在与其他数千名用户一起玩一些视频游戏。您(和其他玩家连接)每秒可以发送和接收 20 个单位。服务器每秒最多可以发送 200 万个单位。这样每个人都很开心并且在线。如果服务器每秒只能发送 20 个单位,那么每个人都会落后,甚至更糟(比如丢包)。

因此,要回答互联网速度是什么,是从向您发送请求到到达服务器、得到响应然后将其返回给您所花费的时间。当然,如果服务器关闭或已完成他的单位空间专用于您,您的请求将被延迟,但这就是互联网的工作方式。

当您下载或流式传输电影时,会发生同样的事情:每次完成下载/流式传输一小部分时,您都在请求新的块。

让我们谈谈一些数字

互联网上的时间以毫秒为单位。如果你只是打开一个终端并做一个简单的ping www.stackoverflow.com 你会得到类似的东西:

Reply from 151.101.1.69: bytes=32 time=36ms TTL=56
Reply from 151.101.1.69: bytes=32 time=36ms TTL=56
Reply from 151.101.1.69: bytes=32 time=36ms TTL=56
Reply from 151.101.1.69: bytes=32 time=36ms TTL=56

time=36ms 是您发送 ping 请求和请求支持您之间经过的时间。

最后

我希望已经清除了一切,在网络上测量时间,是这样的:

- Start counting
- Send a request
- ... 
- Wait..
- ...
- Request turned back
- Stop Counting

** 但我的问题是:我可以用角度来做吗?**

答案是……有点。可能有更好的方法可以做到这一点,但几个月前我也想这样做,我想出了这个主意。

假设我们有一个执行请求的服务:

export class MyService{
  constructor(
    private http: Http
  )

  public sendRequest(){
    return this.http.get(...something);
  }
}

我们的主要组件将进行服务注入并计算经过的时间:

export class MyComponent{
  public timePassed: any;

  constructor(
    private service: MyService
  )

  ngOnInit(): void{
    const startingTime = new Date().getTime();

    this.service.sendRequest()
    .subscribe( res => {
         this.timePassed = ((new Date() - startingTime).getTime())/1000;
    });
  }
}

现在在您的timePassed 变量中,您将获得请求所花费的时间。 正如我所说,由于您的连接速度很慢,或者因为服务器的连接速度很慢,时间可能会发生变化。

您总是必须以互联网速度思考,就像两个人互相交谈一样。总是。 如果您无法将自己的速度与其他人的速度联系起来,那么谈论速度是没有意义的。

【讨论】:

【解决方案2】:

如果你想使用第三方API,有一些专门的测速网站,也提供API访问。例如:

您可以查看相关的 SO 答案here

如果您想在 Angular 中自己实现它,您可以查看我的存储库。我前段时间这样做是为了测试下载速度:angular-speed-test

我使用 Angular HttpClient progress events 跟踪数据传输并据此计算速度。

服务代码:

import { Injectable } from "@angular/core";
import { HttpClient, HttpRequest } from "@angular/common/http";

@Injectable({
  providedIn: "root"
})
export class FileDownloaderService {
  url: string = "some file path for download";

  constructor(private http: HttpClient) {}

  download() {
    const req = new HttpRequest("GET", this.url, {
      responseType: "blob",
      reportProgress: true
    });
    return this.http.request(req);
  }
}

组件

import { Component } from "@angular/core";
import { HttpClient, HttpEventType, HttpResponse } from "@angular/common/http";
import { FileDownloaderService } from "./file-downloader.service";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  constructor(
    private http: HttpClient,
    private downloader: FileDownloaderService
  ) {}

  percentDone: number;
  startTime: any;
  endTime: any;
  currTime: any;
  prevTime: any;
  speed: number = 0;
  bytesReceied: number = 0;
  oldbytes: number = 0;
  unit: string = "Mbps";

  download() {
    this.downloader.download().subscribe(event => {
      if (event.type === HttpEventType.DownloadProgress) {

        //tracking percent received and how much time has passed
        this.percentDone = Math.round((100 * event.loaded) / event.total);    
        this.currTime = new Date().getTime();

        //setting start time
        if (this.percentDone === 0) {
          this.startTime = new Date().getTime();
          this.prevTime = this.startTime;
        }

        //tracking how much data is received
        this.bytesReceied = event.loaded / 1000000;

        //calculating download speed per percent data received
        this.speed =
          (this.bytesReceied - this.oldbytes) /
          ((this.currTime - this.prevTime) / 1000);
        if (this.speed < 1) {
          this.unit = "Kbps";
          this.speed *= 1000;
        } else this.unit = "Mbps";

        //updating previous values
        this.prevTime = this.currTime;    
        this.oldbytes = this.bytesReceied;

        //calculating avg download speed
        if (this.percentDone === 100) {
          this.endTime = new Date().getTime();
          let duration = (this.endTime - this.startTime) / 1000;
          let mbps = event.total / duration / 1000000;
          if (mbps < 1) {
            this.speed = event.total / duration / 1000;
            this.unit = "Kbps";
          } else {
            this.speed = mbps;
            this.unit = "Mbps";
          }
        }

      }
      //download file
      else if (event instanceof HttpResponse) {
        var res: any = event.body;
        var url = window.URL.createObjectURL(res);
        var a = document.createElement("a");
        document.body.appendChild(a);
        a.setAttribute("style", "display: none");
        a.href = url;
        a.download = "SpeedTest_32MB.dat";
        a.click();
        window.URL.revokeObjectURL(url);
        a.remove();
        console.log("File is completely downloaded!");
      }
    });
  }
}

Demo

【讨论】:

    【解决方案3】:

    我认为这完全独立于 Angular。 此外,使用与服务器的连接似乎是执行所需测量的唯一方法。我所知道的所有速度测试页面都使用功能强大、连接良好的服务器,它们从这些服务器接收已知大小的包(或上传到它们)。

    【讨论】:

      【解决方案4】:

      您可以尝试使用this library 来测量与 Netflix 的fast.com 的连接速度。如果您出于某种原因不想使用库,那么实现应该很容易自己编写:-)。

      【讨论】:

        【解决方案5】:

        要在 Angular 中创建像“Internet Speed Test”这样的应用程序,只需使用您要托管应用程序的地址作为服务器端的 URL 和 Web 套接字。然后可以使用 RxJS 订阅 Web Socket 事件并显示结果。

        【讨论】:

          【解决方案6】:

          结帐ng-speed-test 支持 Angular 2+

          • 只需安装:

          npm install ng-speed-test --dev

          • 添加到您的导入中:
          import { SpeedTestModule } from 'ng-speed-test';
          
          @NgModule({
            ...
            imports: [
              SpeedTestModule,
              ...
            ],
            ...
          })
          export class AppModule {}
          

          然后在任何地方使用它:

          constructor(
            private speedTestService:SpeedTestService
          ) {
            this.speedTestService.getMbps().subscribe(
              (speed) => {
                console.log('Your speed is ' + speed);
              }
            );
          }
          

          【讨论】:

            猜你喜欢
            • 2011-05-16
            • 1970-01-01
            • 2011-06-02
            • 2023-03-31
            • 2022-01-11
            • 2021-11-12
            • 2014-07-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多