UNPKG

ngx-network

Version:

get and tracking the network speed with simplest way ever

109 lines 18.2 kB
import { HttpEventType, HttpRequest, } from '@angular/common/http'; import { Inject, Injectable } from '@angular/core'; import { BehaviorSubject, Observable, Subscription, } from 'rxjs'; import { concatMap, filter, finalize, map, takeLast, tap, throttleTime, } from 'rxjs/operators'; import { Units } from './api/units'; import { NGX_NETWORK_CONFIG } from './ngx-network.module'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; export class NgxNetworkService { constructor(config, http) { this.config = config; this.http = http; this.speedChanged$ = new BehaviorSubject({ speed: 0, unit: config.speedUnit, }); this.onSpeedChanged$ = this.speedChanged$.asObservable().pipe(throttleTime(this.config.delay), filter((payload) => payload.speed !== 0)); this.startSendingPayloadSubscription = new Subscription(); this.lastPayloadSize = 0; this.lastTime = 0; } getSpeed() { if (this.startSendingPayloadSubscription) { this.startSendingPayloadSubscription.unsubscribe(); } this.startSendingPayloadSubscription = this.startSendingPayload(this.config.url, false).subscribe(); return this.onSpeedChanged$; } onSpeedChanged() { if (this.startSendingPayloadSubscription) { this.startSendingPayloadSubscription.unsubscribe(); } this.startSendingPayloadSubscription = this.startSendingPayload(this.config.url, true).subscribe(); return this.onSpeedChanged$; } startSendingPayload(url, repeatRequest) { this.lastTime = 0; this.lastPayloadSize = 0; const randomQuery = `q=${Math.round(Math.random() * 99959).toString()}`; if (!repeatRequest) { return this.sendRequest(url, randomQuery).pipe(takeLast(1), tap((payload) => { this.speedChanged$.next(payload); }), map((e) => null)); } return this.sendRequest(url, randomQuery).pipe(tap((payload) => { this.speedChanged$.next(payload); }), finalize(() => { if (!repeatRequest) return; this.startSendingPayloadSubscription.unsubscribe(); this.startSendingPayloadSubscription = this.startSendingPayload(url, repeatRequest).subscribe(); }), map((e) => null)); } sendRequest(url, params) { const request = new HttpRequest('GET', url, { params, responseType: 'arraybuffer', reportProgress: true, }); return this.http .request(request) .pipe(concatMap((httpEvent) => this.handleHttpEvents(httpEvent))); } handleHttpEvents(e) { return new Observable((subscriber) => { if (e.type === HttpEventType.DownloadProgress) { let currentTime = Date.now(); const elapseTimeForEveryPayload = currentTime - this.lastTime; const elapseTimeSecs = elapseTimeForEveryPayload / 1000; let speed = this.speedChanged$.getValue().speed.toString(); const currentPayloadSize = e.loaded; const downloadPayloadSize = Math.abs(currentPayloadSize - this.lastPayloadSize); switch (this.config.speedUnit) { case Units['kb/s']: speed = Number(downloadPayloadSize / 1024 / elapseTimeSecs).toFixed(3); break; case Units['mb/s']: speed = Number(downloadPayloadSize / Math.pow(1024, 2) / elapseTimeSecs).toFixed(3); break; case Units['gb/s']: speed = Number(downloadPayloadSize / Math.pow(1024, 3) / elapseTimeSecs).toFixed(3); break; case Units['tb/s']: speed = Number(downloadPayloadSize / Math.pow(1024, 4) / elapseTimeSecs).toFixed(3); break; } this.lastPayloadSize = e.loaded; this.lastTime = Date.now(); subscriber.next({ speed: Number(Number(speed) === 0 ? this.speedChanged$.getValue().speed : speed), unit: this.config.speedUnit, }); } subscriber.complete(); }); } } NgxNetworkService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NgxNetworkService, deps: [{ token: NGX_NETWORK_CONFIG }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); NgxNetworkService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NgxNetworkService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NgxNetworkService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [NGX_NETWORK_CONFIG] }] }, { type: i1.HttpClient }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LW5ldHdvcmsuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1uZXR3b3JrL3NyYy9saWIvbmd4LW5ldHdvcmsuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0wsYUFBYSxFQUNiLFdBQVcsR0FDWixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFDTCxlQUFlLEVBQ2YsVUFBVSxFQUVWLFlBQVksR0FDYixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFDTCxTQUFTLEVBQ1QsTUFBTSxFQUNOLFFBQVEsRUFDUixHQUFHLEVBRUgsUUFBUSxFQUNSLEdBQUcsRUFDSCxZQUFZLEdBQ2IsTUFBTSxnQkFBZ0IsQ0FBQztBQUd4QixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7QUFJMUQsTUFBTSxPQUFPLGlCQUFpQjtJQU01QixZQUNzQyxNQUFjLEVBQzFDLElBQWdCO1FBRFksV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUMxQyxTQUFJLEdBQUosSUFBSSxDQUFZO1FBRXhCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxlQUFlLENBQUM7WUFDdkMsS0FBSyxFQUFFLENBQUM7WUFDUixJQUFJLEVBQUUsTUFBTSxDQUFDLFNBQVM7U0FDdkIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDLElBQUksQ0FDM0QsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQy9CLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssS0FBSyxD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aWVudCxcbiAgSHR0cEV2ZW50LFxuICBIdHRwRXZlbnRUeXBlLFxuICBIdHRwUmVxdWVzdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIE9ic2VydmFibGUsXG4gIFN1YnNjcmliZXIsXG4gIFN1YnNjcmlwdGlvbixcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBjb25jYXRNYXAsXG4gIGZpbHRlcixcbiAgZmluYWxpemUsXG4gIG1hcCxcbiAgcmVwZWF0LFxuICB0YWtlTGFzdCxcbiAgdGFwLFxuICB0aHJvdHRsZVRpbWUsXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4vYXBpL2NvbmZpZyc7XG5pbXBvcnQgeyBOZXR3b3JrU3BlZWRJbmZvIH0gZnJvbSAnLi9hcGkvbmV0d29yay1zcGVlZC1pbmZvJztcbmltcG9ydCB7IFVuaXRzIH0gZnJvbSAnLi9hcGkvdW5pdHMnO1xuaW1wb3J0IHsgTkdYX05FVFdPUktfQ09ORklHIH0gZnJvbSAnLi9uZ3gtbmV0d29yay5tb2R1bGUnO1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOidyb290J1xufSlcbmV4cG9ydCBjbGFzcyBOZ3hOZXR3b3JrU2VydmljZSB7XG4gIHByaXZhdGUgc3BlZWRDaGFuZ2VkJDogQmVoYXZpb3JTdWJqZWN0PE5ldHdvcmtTcGVlZEluZm8+O1xuICBwcml2YXRlIG9uU3BlZWRDaGFuZ2VkJDogT2JzZXJ2YWJsZTxOZXR3b3JrU3BlZWRJbmZvPjtcbiAgcHJpdmF0ZSBzdGFydFNlbmRpbmdQYXlsb2FkU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgbGFzdFRpbWU6IG51bWJlcjtcbiAgcHJpdmF0ZSBsYXN0UGF5bG9hZFNpemU6IG51bWJlcjtcbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChOR1hfTkVUV09SS19DT05GSUcpIHByaXZhdGUgY29uZmlnOiBDb25maWcsXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50XG4gICkge1xuICAgIHRoaXMuc3BlZWRDaGFuZ2VkJCA9IG5ldyBCZWhhdmlvclN1YmplY3Qoe1xuICAgICAgc3BlZWQ6IDAsXG4gICAgICB1bml0OiBjb25maWcuc3BlZWRVbml0LFxuICAgIH0pO1xuICAgIHRoaXMub25TcGVlZENoYW5nZWQkID0gdGhpcy5zcGVlZENoYW5nZWQkLmFzT2JzZXJ2YWJsZSgpLnBpcGUoXG4gICAgICB0aHJvdHRsZVRpbWUodGhpcy5jb25maWcuZGVsYXkpLFxuICAgICAgZmlsdGVyKChwYXlsb2FkKSA9PiBwYXlsb2FkLnNwZWVkICE9PSAwKVxuICAgICk7XG4gICAgdGhpcy5zdGFydFNlbmRpbmdQYXlsb2FkU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICAgIHRoaXMubGFzdFBheWxvYWRTaXplID0gMDtcbiAgICB0aGlzLmxhc3RUaW1lID0gMDtcbiAgfVxuICBnZXRTcGVlZCgpIHtcbiAgICBpZiAodGhpcy5zdGFydFNlbmRpbmdQYXlsb2FkU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnN0YXJ0U2VuZGluZ1BheWxvYWRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgdGhpcy5zdGFydFNlbmRpbmdQYXlsb2FkU3Vic2NyaXB0aW9uID0gdGhpcy5zdGFydFNlbmRpbmdQYXlsb2FkKFxuICAgICAgdGhpcy5jb25maWcudXJsLFxuICAgICAgZmFsc2VcbiAgICApLnN1YnNjcmliZSgpO1xuICAgIHJldHVybiB0aGlzLm9uU3BlZWRDaGFuZ2VkJDtcbiAgfVxuICBvblNwZWVkQ2hhbmdlZCgpOiBPYnNlcnZhYmxlPE5ldHdvcmtTcGVlZEluZm8+IHtcbiAgICBpZiAodGhpcy5zdGFydFNlbmRpbmdQYXlsb2FkU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnN0YXJ0U2VuZGluZ1BheWxvYWRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgdGhpcy5zdGFydFNlbmRpbmdQYXlsb2FkU3Vic2NyaXB0aW9uID0gdGhpcy5zdGFydFNlbmRpbmdQYXlsb2FkKFxuICAgICAgdGhpcy5jb25maWcudXJsLFxuICAgICAgdHJ1ZVxuICAgICkuc3Vic2NyaWJlKCk7XG4gICAgcmV0dXJuIHRoaXMub25TcGVlZENoYW5nZWQkO1xuICB9XG4gIHByaXZhdGUgc3RhcnRTZW5kaW5nUGF5bG9hZCh1cmw6IHN0cmluZywgcmVwZWF0UmVxdWVzdDogYm9vbGVhbik6IE9ic2VydmFibGU8bnVsbD4ge1xuICAgIHRoaXMubGFzdFRpbWUgPSAwO1xuICAgIHRoaXMubGFzdFBheWxvYWRTaXplID0gMDtcbiAgICBjb25zdCByYW5kb21RdWVyeSA9IGBxPSR7TWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogOTk5NTkpLnRvU3RyaW5nKCl9YDtcbiAgICBpZighcmVwZWF0UmVxdWVzdCl7XG4gICAgICAgcmV0dXJuIHRoaXMuc2VuZFJlcXVlc3QodXJsLCByYW5kb21RdWVyeSkucGlwZShcbiAgICAgICAgdGFrZUxhc3QoMSksXG4gICAgICAgIHRhcCgocGF5bG9hZCkgPT4ge1xuICAgICAgICAgIHRoaXMuc3BlZWRDaGFuZ2VkJC5uZXh0KHBheWxvYWQpO1xuICAgICAgICB9KSxcbiAgICAgICAgbWFwKChlKSA9PiBudWxsKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2VuZFJlcXVlc3QodXJsLCByYW5kb21RdWVyeSkucGlwZShcbiAgICAgIHRhcCgocGF5bG9hZCkgPT4ge1xuICAgICAgICB0aGlzLnNwZWVkQ2hhbmdlZCQubmV4dChwYXlsb2FkKTtcbiAgICAgIH0pLFxuICAgICAgZmluYWxpemUoKCkgPT4ge1xuICAgICAgICBpZiAoIXJlcGVhdFJlcXVlc3QpIHJldHVybjtcbiAgICAgICAgdGhpcy5zdGFydFNlbmRpbmdQYXlsb2FkU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuc3RhcnRTZW5kaW5nUGF5bG9hZFN1YnNjcmlwdGlvbiA9IHRoaXMuc3RhcnRTZW5kaW5nUGF5bG9hZChcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcmVwZWF0UmVxdWVzdFxuICAgICAgICApLnN1YnNjcmliZSgpO1xuICAgICAgfSksXG4gICAgICBtYXAoKGUpID0+IG51bGwpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc2VuZFJlcXVlc3QodXJsOiBzdHJpbmcsIHBhcmFtczogc3RyaW5nKSB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBIdHRwUmVxdWVzdCgnR0VUJywgdXJsLCB7XG4gICAgICBwYXJhbXMsXG4gICAgICByZXNwb25zZVR5cGU6ICdhcnJheWJ1ZmZlcicsXG4gICAgICByZXBvcnRQcm9ncmVzczogdHJ1ZSxcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmh0dHBcbiAgICAgIC5yZXF1ZXN0KHJlcXVlc3QpXG4gICAgICAucGlwZShcbiAgICAgICAgY29uY2F0TWFwKChodHRwRXZlbnQ6IEh0dHBFdmVudDxhbnk+KSA9PlxuICAgICAgICAgIHRoaXMuaGFuZGxlSHR0cEV2ZW50cyhodHRwRXZlbnQpXG4gICAgICAgIClcbiAgICAgICk7XG4gIH1cbiAgcHJpdmF0ZSBoYW5kbGVIdHRwRXZlbnRzKGU6IEh0dHBFdmVudDxBcnJheUJ1ZmZlcj4pIHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8TmV0d29ya1NwZWVkSW5mbz4oXG4gICAgICAoc3Vic2NyaWJlcjogU3Vic2NyaWJlcjxOZXR3b3JrU3BlZWRJbmZvPikgPT4ge1xuICAgICAgICBpZiAoZS50eXBlID09PSBIdHRwRXZlbnRUeXBlLkRvd25sb2FkUHJvZ3Jlc3MpIHtcbiAgICAgICAgICBsZXQgY3VycmVudFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIGNvbnN0IGVsYXBzZVRpbWVGb3JFdmVyeVBheWxvYWQgPSBjdXJyZW50VGltZSAtIHRoaXMubGFzdFRpbWU7XG4gICAgICAgICAgY29uc3QgZWxhcHNlVGltZVNlY3MgPSBlbGFwc2VUaW1lRm9yRXZlcnlQYXlsb2FkIC8gMTAwMDtcbiAgICAgICAgICBsZXQgc3BlZWQ6IHN0cmluZyA9IHRoaXMuc3BlZWRDaGFuZ2VkJC5nZXRWYWx1ZSgpLnNwZWVkLnRvU3RyaW5nKCk7XG4gICAgICAgICAgY29uc3QgY3VycmVudFBheWxvYWRTaXplID0gZS5sb2FkZWQ7XG4gICAgICAgICAgY29uc3QgZG93bmxvYWRQYXlsb2FkU2l6ZSA9IE1hdGguYWJzKFxuICAgICAgICAgICAgY3VycmVudFBheWxvYWRTaXplIC0gdGhpcy5sYXN0UGF5bG9hZFNpemVcbiAgICAgICAgICApO1xuICAgICAgICAgIHN3aXRjaCAodGhpcy5jb25maWcuc3BlZWRVbml0KSB7XG4gICAgICAgICAgICBjYXNlIFVuaXRzWydrYi9zJ106XG4gICAgICAgICAgICAgIHNwZWVkID0gTnVtYmVyKFxuICAgICAgICAgICAgICAgIGRvd25sb2FkUGF5bG9hZFNpemUgLyAxMDI0IC8gZWxhcHNlVGltZVNlY3NcbiAgICAgICAgICAgICAgKS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVW5pdHNbJ21iL3MnXTpcbiAgICAgICAgICAgICAgc3BlZWQgPSBOdW1iZXIoXG4gICAgICAgICAgICAgICAgZG93bmxvYWRQYXlsb2FkU2l6ZSAvIE1hdGgucG93KDEwMjQsIDIpIC8gZWxhcHNlVGltZVNlY3NcbiAgICAgICAgICAgICAgKS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVW5pdHNbJ2diL3MnXTpcbiAgICAgICAgICAgICAgc3BlZWQgPSBOdW1iZXIoXG4gICAgICAgICAgICAgICAgZG93bmxvYWRQYXlsb2FkU2l6ZSAvIE1hdGgucG93KDEwMjQsIDMpIC8gZWxhcHNlVGltZVNlY3NcbiAgICAgICAgICAgICAgKS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVW5pdHNbJ3RiL3MnXTpcbiAgICAgICAgICAgICAgc3BlZWQgPSBOdW1iZXIoXG4gICAgICAgICAgICAgICAgZG93bmxvYWRQYXlsb2FkU2l6ZSAvIE1hdGgucG93KDEwMjQsIDQpIC8gZWxhcHNlVGltZVNlY3NcbiAgICAgICAgICAgICAgKS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5sYXN0UGF5bG9hZFNpemUgPSBlLmxvYWRlZDtcbiAgICAgICAgICB0aGlzLmxhc3RUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICBzdWJzY3JpYmVyLm5leHQoe1xuICAgICAgICAgICAgc3BlZWQ6IE51bWJlcihcbiAgICAgICAgICAgICAgTnVtYmVyKHNwZWVkKSA9PT0gMCA/IHRoaXMuc3BlZWRDaGFuZ2VkJC5nZXRWYWx1ZSgpLnNwZWVkIDogc3BlZWRcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB1bml0OiB0aGlzLmNvbmZpZy5zcGVlZFVuaXQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiJdfQ==