Skip to content

Commit

Permalink
Fix: Fix failover in access network info
Browse files Browse the repository at this point in the history
The previous method was not reliable and failing when rate limit on ipinfo, changed so when it fails request the net info from ipv4.
  • Loading branch information
Victor Lopez committed Oct 2, 2024
1 parent 9ada809 commit 172169b
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 123 deletions.
2 changes: 1 addition & 1 deletion src/app/searchcountry/searchcountry.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,7 @@ export class SearchcountryPage {
/* Store school id and giga id inside storage */
let countryData = {};

this.networkService.getAccessInformation().subscribe((c) => {
this.networkService.getNetInfo().then((c) => {
console.log(c);
this.selectedCountry = c.country;
this.detectedCountry = c.country;
Expand Down
14 changes: 7 additions & 7 deletions src/app/services/measurement-client.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class MeasurementClientService {
await this.finalizeMeasurement(measurementRecord);
} catch (error) {
console.error('Error running ndt7 test:', error);
this.broadcastMeasurementStatus('error', { error: error.message });
this.broadcastMeasurementStatus('onError', { error: error.message });
}
}

Expand All @@ -109,13 +109,13 @@ export class MeasurementClientService {
};
}

private getTestInfo() {
return forkJoin({
accessInformation: this.networkService.getAccessInformation(),
mlabInformation: this.mlabService.findServer(
private async getTestInfo() {
return {
accessInformation: await this.networkService.getNetInfo(),
mlabInformation: await this.mlabService.findServer(
this.settingsService.get('metroSelection')
),
}).toPromise();
).toPromise(),
};
}

private getTestCallbacks(measurementRecord: any) {
Expand Down
166 changes: 60 additions & 106 deletions src/app/services/network.service.ts
Original file line number Diff line number Diff line change
@@ -1,135 +1,89 @@
import { Injectable } from '@angular/core';
import { map, catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
import { throwError } from 'rxjs';
import { Network } from '@awesome-cordova-plugins/network/ngx';
import { HttpClient, HttpHeaders } from '@angular/common/http';


type Ip4Data = {
organization: string;
country: string;
asn: number;
area_code: string;
organization_name: string;
country_code: string;
country_code3: string;
continent_code: string;
latitude: string;
region: string;
city: string;
longitude: string;
accuracy: number;
ip: string;
timezone: string;
};

type IpInfoData = {
ip: string;
hostname: string;
city: string;
region: string;
country: string;
loc: string;
org: string;
postal: string;
timezone: string;
};
@Injectable({
providedIn: 'root'
})
export class NetworkService {
accessServiceUrl = 'https://ipinfo.io?token=9906baf67eda8b';
// accessServiceUrl = 'https://ipinfo.io?token=060bdd9da6a22f'; //ONLY FOR LOCAL DEV TESTING
// accessServiceUrl = 'https://ipinfo.io?token=060bdd9da6a22f'; //ONLY FOR LOCAL DEV TESTING
headers: any;
options: any;
currentAccessInformation: any;
connectionType = {
'icon': 'ion-help',
'label': 'Unknown',
icon: 'ion-help',
label: 'Unknown',
}
constructor( private http: HttpClient, private network: Network ) {
constructor(private http: HttpClient, private network: Network) {
const headersItem = new HttpHeaders({
'Content-Type': 'application/json'
});
this.headers = headersItem;
}

/**
* Return client network information from ipinfo
* @returns current access information
* Retrieves network information.
* @returns {Promise<any>} A promise that resolves to the network information.
*/
getAccessInformation(){
this.options = {headers: this.headers};
// this.currentAccessInformation = this.getNetworkInfo();
// return this.currentAccessInformation;
var response = this.http.get(this.accessServiceUrl, this.options)
.pipe(
map(
(response: any) => {
console.log('resss', response)
if(!response){
this.currentAccessInformation = this.getNetworkInfo();
return this.currentAccessInformation;
}
this.currentAccessInformation = response;
let asnRegex = new RegExp('^(AS[0-9]+)\\w+(.+)');
this.currentAccessInformation.asn = this.currentAccessInformation.org.replace(asnRegex, "$1");
this.currentAccessInformation.org = this.currentAccessInformation.org.replace(asnRegex, "$2");
return this.currentAccessInformation;
}
)
);
if(response == null || response == undefined){
console.log('errror')
} else{
console.log('no error')
}
return response;


}
async getNetworkInfo() {
async getNetInfo() {
console.log('getNetInfo');
const options = { headers: this.headers };
let response = null;
try {
const response = await fetch('https://ipv4.geojs.io/v1/ip/geo.json');
const data = await response.json();

return data;
response = await this.http.get(this.accessServiceUrl, options).toPromise<any>();
} catch (error) {
console.log('Error:', error);
return null;
console.error('Error:', error);
const ipGeoResponse = await fetch('https://ipv4.geojs.io/v1/ip/geo.json');
const ipGeoData = await ipGeoResponse.json();
return this.mapData(ipGeoData);
}
}
/**
*
* @param connectionClass
* @returns Connection information of client
*/
getConnectionInformation(connectionClass){
let connectSubscription = this.network.onConnect().subscribe(() => {
console.log('network connected!');
// `unknown`, `ethernet`, `wifi`, `2g`, `3g`, `4g`, `cellular`, `none`
setTimeout(() => {
switch(connectionClass){
case 'wifi':
this.connectionType.icon = 'ion-wifi';
this.connectionType.label = 'Wi-Fi';
break;
case '2g':
this.connectionType.icon = 'ion-connection-bars';
this.connectionType.label = 'Mobile Data (2G)';
break;
case '3g':
this.connectionType.icon = 'ion-connection-bars';
this.connectionType.label = 'Mobile Data (3G)';
break;
case '4g':
this.connectionType.icon = 'ion-connection-bars';
this.connectionType.label = 'Mobile Data (4G)';
break;
case 'cellular':
this.connectionType.icon = 'ion-connection-bars';
this.connectionType.label = 'Mobile Data';
break;
case 'ethernet':
this.connectionType.icon = 'ion-connection-bars';
this.connectionType.label = 'Mobile Data';
break;
default:
break;
}
}, 3000);
});

// stop connect watch
connectSubscription.unsubscribe();
return this.connectionType;
return response;
}

/**
*
* @returns current network information
*/
currentConnectionInformation(){
let connectionClass = undefined;
connectionClass = this.network.type;
return this.getConnectionInformation(connectionClass);
}

/**
* Private function to handle error
* @param error
* @returns Error
*/
private handleError(error: Response) {
return throwError(error);
private mapData(source: Ip4Data): IpInfoData {
return {
ip: source.ip,
hostname: source.ip,
city: source.city || "",
region: source.region || "",
country: source.country_code,
loc: `${source.latitude},${source.longitude}`,
org: source.organization || source.organization_name,
postal: "",
timezone: source.timezone,
};
}
}
18 changes: 9 additions & 9 deletions src/app/services/schedule.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class ScheduleService {
private sharedService: SharedService,
private networkService: NetworkService,
private customScheduleService: CustomScheduleService
) {}
) { }

initiate() {
this.watch();
Expand Down Expand Up @@ -72,7 +72,7 @@ export class ScheduleService {
scheduleSemaphore.choice !== undefined &&
currentTime > scheduleSemaphore.choice
) {
const networkInfo = await this.networkService.getNetworkInfo();
const networkInfo = await this.networkService.getNetInfo();
if (networkInfo === null) {
console.log('Network not available, skipping schedule check.');
this.storageService.set('measurementOfReconnect', true);
Expand All @@ -81,13 +81,13 @@ export class ScheduleService {
}
console.log(
'On ' +
new Date(currentTime).toUTCString() +
' found scheduled test covering ' +
new Date(scheduleSemaphore.start).toUTCString() +
' and ' +
new Date(scheduleSemaphore.end).toUTCString() +
' scheduled to run near ' +
new Date(scheduleSemaphore.choice).toUTCString()
new Date(currentTime).toUTCString() +
' found scheduled test covering ' +
new Date(scheduleSemaphore.start).toUTCString() +
' and ' +
new Date(scheduleSemaphore.end).toUTCString() +
' scheduled to run near ' +
new Date(scheduleSemaphore.choice).toUTCString()
);
console.log('Found scheduled measurement ready, triggering.');
this.storageService.set('lastMeasurement', currentTime);
Expand Down

0 comments on commit 172169b

Please sign in to comment.