如何在Angular中计算下载/上传互联网速度

时间:2018-09-04 17:57:03

标签: angular

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

请求API并不是最好的解决方案,因为如果服务器本身因负载而减慢速度,则结果将是错误的。

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

有什么想法吗?

6 个答案:

答案 0 :(得分:9)

什么是互联网速度?

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

您正在与其他数千名用户一起玩一些电子游戏。您(和其他播放器的连接)每秒可以发送和接收20个单位。服务器每秒最多可以发送2百万个单位。这样,每个人都可以开心并在线。如果服务器每秒只能发送20个单位,那么每个人都会落后,甚至更糟(就像包裹丢失)。

因此,要回答互联网速度是多少,即从发送给您的请求开始,到达服务器,进行响应,然后再将其转回给您的时间。当然,如果服务器宕机或已用完自己的主机空间供您使用,您的请求将被延迟,但这就是Internet的工作方式。

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

让我们谈谈一些数字

时间浪费在互联网上,以毫秒为单位。如果您只是打开终端并执行简单的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 couting
- Send a request
- ... 
- Wait..
- ...
- Request turned back
- Stop Counting

**但是我的问题是:我可以按角度进行吗? **

答案是.. Kinda。也许有更好的方法可以做到这一点,但是几个月前我也想这样做,然后我想到了这个主意。

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

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变量中,您将拥有请求所花费的时间。 正如我所说,时间可能会由于您的连接速度缓慢或服务器的连接速度缓慢而改变。

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

答案 1 :(得分:4)

如果您想使用第三方API,则有一些专用的速度测试网站,它们也提供API访问。例如:

您可以签出相关的SO答案here

OR

如果您想自己在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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

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

答案 4 :(得分:2)

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

答案 5 :(得分:0)

支持Angular 2+的Checkout ng-speed-test

  • 只需安装:

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);
    }
  );
}