Skip to content

Commit

Permalink
Merge pull request #149 from radarlabs/latency-ws
Browse files Browse the repository at this point in the history
latency calcs with web sockets
  • Loading branch information
nickpatrick authored Jan 23, 2024
2 parents 92bb15a + deedac7 commit 8629988
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 50 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Radar.initialize('prj_test_pk_...', { /* options */ });
Add the following script in your `html` file
```html
<script src="https://js.radar.com/v4.1.16/radar.min.js"></script>
<script src="https://js.radar.com/v4.1.17/radar.min.js"></script>
```

Then initialize the Radar SDK
Expand All @@ -73,8 +73,8 @@ To create a map, first initialize the Radar SDK with your publishable key. Then
```html
<html>
<head>
<link href="https://js.radar.com/v4.1.16/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.1.16/radar.min.js"></script>
<link href="https://js.radar.com/v4.1.17/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.1.17/radar.min.js"></script>
</head>

<body>
Expand All @@ -98,8 +98,8 @@ To create an autocomplete input, first initialize the Radar SDK with your publis
```html
<html>
<head>
<link href="https://js.radar.com/v4.1.16/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.1.16/radar.min.js"></script>
<link href="https://js.radar.com/v4.1.17/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.1.17/radar.min.js"></script>
</head>

<body>
Expand Down Expand Up @@ -130,8 +130,8 @@ To power [geofencing](https://radar.com/documentation/geofencing/overview) exper
```html
<html>
<head>
<link href="https://js.radar.com/v4.1.16/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.1.16/radar.min.js"></script>
<link href="https://js.radar.com/v4.1.17/radar.css" rel="stylesheet">
<script src="https://js.radar.com/v4.1.17/radar.min.js"></script>
</head>

<body>
Expand Down
21 changes: 3 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "radar-sdk-js",
"version": "4.1.16",
"version": "4.1.17",
"description": "Web Javascript SDK for Radar, location infrastructure for mobile and web apps.",
"homepage": "https://radar.com",
"type": "module",
Expand Down Expand Up @@ -49,9 +49,7 @@
"typescript": "^5.0.4"
},
"dependencies": {
"@types/geojson": "^7946.0.10",
"detectincognitojs": "^1.3.0",
"jsrsasign": "^11.0.0"
"@types/geojson": "^7946.0.10"
},
"peerDependencies": {
"maplibre-gl": "^2.4.0 || ^3.0.0"
Expand Down
62 changes: 42 additions & 20 deletions src/api/track.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import { detectIncognito } from 'detectincognitojs';
// @ts-ignore
import { KJUR } from 'jsrsasign';

import SDK_VERSION from '../version';
import Config from '../config';
import Device from '../device';
Expand All @@ -11,6 +7,8 @@ import Navigator from '../navigator';
import Session from '../session';
import Storage from '../storage';
import TripsAPI from './trips';
import { signJWT } from '../util/jwt';
import { ping } from '../util/net';

import type { RadarTrackParams, RadarTrackResponse } from '../types';

Expand Down Expand Up @@ -90,15 +88,11 @@ class TrackAPI {

let response: any;
if (fraud) {
let incognito = false;
try {
const result = await detectIncognito();
incognito = result.isPrivate;
} catch (err: any) {
Logger.warn(`Error detecting incognito mode: ${err.message}`);
}

const host = 'https://api-verified.radar.io';
const pingHost = 'ping.radar-verify.com';

const lang = navigator.language;
const langs = navigator.languages;

const { dk }: any = await Http.request({
host,
Expand All @@ -115,18 +109,35 @@ class TrackAPI {
},
});

const header = JSON.stringify({
alg: 'HS256',
typ: 'JWT',
});
const payload = JSON.stringify({
let sclVal = -1;
let cslVal = -1;
try {
const [sclRes, csl] = await Promise.all([
Http.request({
host: `https://${pingHost}`,
method: 'GET',
path: 'ping',
}),
ping(`wss://${pingHost}`),
]);
const { scl }: any = sclRes;
sclVal = scl;
cslVal = csl;
} catch (err) {
// do nothing, send scl = -1 and csl = -1
}

const payload = {
payload: JSON.stringify({
...body,
incognito,
scl: sclVal,
csl: cslVal,
lang,
langs,
}),
});
};

const token = KJUR.jws.JWS.sign('HS256', header, payload, { utf8: dk });
const token = await signJWT(payload, dk);

response = await Http.request({
host,
Expand All @@ -139,6 +150,17 @@ class TrackAPI {
'X-Radar-Body-Is-Token': 'true',
},
});

if (options.debug && response && response.user) {
if (!response.user.metadata) {
response.user.metadata = {};
}

response.user.metadata['radar:debug'] = {
sclVal,
cslVal,
};
}
} else {
response = await Http.request({
method: 'POST',
Expand Down
28 changes: 28 additions & 0 deletions src/util/jwt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const base64Encode = (str: string): string =>
btoa(str).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');

export const signJWT = async (payload: object, key: string): Promise<string> => {
const encoder = new TextEncoder();

const encodedHeader = base64Encode(JSON.stringify({
alg: 'HS256',
typ: 'JWT',
}));
const encodedPayload = base64Encode(JSON.stringify(payload));

const keyData = encoder.encode(key);
const messageData = encoder.encode(`${encodedHeader}.${encodedPayload}`);

const cryptoKey = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: { name: 'SHA-256' } },
false,
['sign']
);

const signatureArrayBuffer = await crypto.subtle.sign('HMAC', cryptoKey, messageData);
const signature = base64Encode(String.fromCharCode(...Array.from(new Uint8Array(signatureArrayBuffer))));

return `${encodedHeader}.${encodedPayload}.${signature}`;
};
54 changes: 54 additions & 0 deletions src/util/net.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Logger from '../logger';

export const ping = (host: string): Promise<any> => {
return new Promise((resolve) => {
const socket = new WebSocket(host);

let pings = 0;
const latencies: number[] = [];
let pingInterval: any;
let timeoutInterval: any;

const ping = () => {
pings++;

const start = Date.now();
socket.send('ping');

socket.onmessage = (event) => {
if (event.data === 'pong') {
const latency = Date.now() - start;
latencies.push(latency);

if (pings >= 3) {
clearInterval(pingInterval);
clearInterval(timeoutInterval);
const median = latencies.sort((a, b) => a - b)[1];
socket.close();
resolve(median);
}
}
};
}

const timeout = () => {
Logger.warn('Socket timeout');
clearInterval(pingInterval);
clearInterval(timeoutInterval);
socket.close();
resolve(-1);
}

socket.onerror = (err) => {
Logger.warn('Error opening socket');
socket.close();
resolve(-1);
};

socket.onopen = () => {
ping();
pingInterval = setInterval(ping, 1000);
timeoutInterval = setInterval(timeout, 10000);
};
});
};
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default '4.1.16';
export default '4.1.17';

0 comments on commit 8629988

Please sign in to comment.