我想计算Angular中的下载和上传互联网速度。
请求API并不是最好的解决方案,因为如果服务器本身因负载而减慢速度,则结果将是错误的。
也许有一些针对Angular的解决方案,为此使用了特殊的网站(例如speedtest.net)。
有什么想法吗?
答案 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!");
}
});
}
}
答案 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);
}
);
}