2.0.9 • Published 11 months ago

@samknows/web-sdk v2.0.9

Weekly downloads
-
License
SEE LICENSE IN RE...
Repository
github
Last release
11 months ago

SamKnows Web SDK: web-based speed test

Overview

The SamKnows Web SDK provides a way for users to manually run speed tests against SamKnows measurement servers without the need for a hardware agent (such as a Whitebox or embedded solution) or an app on their mobile device.

This library allows you to completely configure the appearance and behaviour of the speed test.

Table of contents

Install

You can either use a javascript package manager or a CDN to add the WebSDK on any HTML page and access the global SpeedTest variable..

The project only contains 3 files: README, speed-test.js and speed-test.d.ts. The speed-test.js file is bundled using the UMD syntax, so you can import it using a bundler tool such as RequireJS, Browserify or Webpack, or you can add the file directly to your site and use the global SpeedTest variable.

  • npm
$ npm install @samknows/web-sdk --save
  • yarn
$ yarn add @samknows/web-sdk
  • CDN
<script src="https://unpkg.com/@samknows/web-sdk"></script>

Licence key

You will need a valid licence key in order to use this library. Please contact your SamKnows account manager to request a licence key.

Once you have a licence key, you will need to pass it to the WebSDK via the options (see How to use

Web SDK API

Supported tests

Due to the nature of the browser, the web test only runs a subset of the tests available in the embedded SDK or mobile apps:

  • Latency
  • Jitter (derived from the latency test)
  • Download speed
  • Upload speed

Find fastest server

The latency test is ran on all test server to find which one is the fastest. results.fastestServer is used on some clients website to show which one it was tested against.

Running all tests in one go

The Web SDK is the most flexible way of using the web-based speed test, handling only the logic of running the test and leaving the interface completely up to you.

To initialise and start the test, create a new instance of the SpeedTest object imported from the library:

// This line is not needed if you're using the CDN
import SpeedTest from '@samknows/web-sdk';

const st = new SpeedTest({
  global: {
    licenceKey: 'YOUR-LICENCE-KEY'
  }
});

You can pass options into the constructor (which will be covered shortly) but the defaults are usually reasonable.

The speed test will immediately start running. The returned object is an event emitter which can be used as follows:

st.on('progress', function (results) {
  // results is an object containing the test results
});

The progress event is emitted whenever some data arrives from the server and the result of the currently in progress test is updated. This event can be emitted very often so can be a performance bottleneck if you try to animate the page on this event - it is more efficient to store the results to a variable and animate the page on requestAnimationFrame instead.

st.on('progress-warmup', function (results) {
  // results is an object containing the test results
});

The download and upload tests have warmup phases where they're downloading data, but the result isn't counted towards the final result. The progress-warmup event is emitted as if the test is running, but then the duration and bytes sent data is reset after the warmup phase and the test phase starts again from 0.

st.on('test-done', function (testName, results) {
  // testName is the name of the test that just finished
  // results is an object containing the test results
});

The test-done event is emitted when a test finishes running (and thus, when the next one begins). It is useful for updating the user interface between tests.

Unlike most of the other events, this one has two arguments - the first is the name of the test that just finished, and the second is the object containing results as in the other events.

st.on('done', function (results) {
  // results is an object containing the test results
});

The done event is emitted once when the test has finished running and the tests have been cleaned up (e.g. ensuring that all connections are now closed).

st.on('error', function (err) {
  // err is an Error object
});

The error event is emitted when the test fails to complete. This can be for any number of reasons - check the error message for more info. Usually it's because of a network problem.

Results ingestions

The speed test sends the results of the test back to the SamKnows ingestion server, configuration for which can be found in the ingestion object. You will probably never need to change the ingestionApi property, but you'll need to set the panelId to the ID of the panel you want the results reporting to.

The st object will emit a test-id event with the ID of the stored test once the ingestion API returns successful - this will happen after the done event.

Running one test at a time

If you want to only run a specific test, in any order you want, you can set the immediate global option to false when creating the web test:

const st = new SpeedTest({
  global: {
    licenceKey: 'YOUR-LICENCE-KEY',
    immediate: false
  },
});

This will find the nearest target right away and trigger the ready event when ready to test. You can then run one of the 3 tests: download, upload, or latency (includes jitter) in any order you want.

st.on('ready', () => {
  st.run('download');
});

To give you more flexibility, you will need to ingest the results yourself.

You can use the same exact same events as above (progress, test-done, error). Only the done event will not be triggered as it indicates all tests ran and have been ingested (which doesn't happen for individual tests).

The results object

While the speed test is in progress, the results object will look something like this:

{
  "inProgress": "download",
  "latency": {
  "round_trip_time": 6489,
    "jitter": 919,
    "minLatency": 5.570000001229346,
    "duration": 88075,
    "successes": 10,
    "failures": 0,
    "target": "10.0.0.106",
    "percentage_complete": 100,
    "utc_datetime": "2018-06-12T10:27:30.599Z"
  },
  "download": {
    "bytes_sec": 6964165,
    "mbps": 55.713320546338146,
    "bytes_total": 69639840,
    "duration": 9999740,
    "successes": 1,
    "failures": 0,
    "target": "10.0.0.106",
    "utc_datetime": "2018-06-12T10:27:42.607Z"
  }
}

And when it is done, it will look something like this:

{
  "latency": {
    "round_trip_time": 53348,
    "jitter": 27507,
    "minLatency": 25.84000000206288,
    "duration": 631070,
    "successes": 10,
    "failures": 0,
    "target": "10.0.0.106",
    "utc_datetime": "2018-06-12T10:28:19.779Z",
    "percentage_complete": 100
  },
  "download": {
    "bytes_sec": 6721736,
    "mbps": 55.713320546338146,
    "bytes_total": 69639840,
    "duration": 9998540,
    "successes": 1,
    "failures": 0,
    "target": "10.0.0.106",
    "utc_datetime": "2018-06-12T10:28:31.778Z",
    "percentage_complete": 100
  },
  "upload": {
    "bytes_sec": 1381142,
    "mbps": 11.66215590350929,
    "bytes_total": 14286848,
    "duration": 9679920,
    "successes": 1,
    "failures": 0,
    "target": "10.0.0.106",
    "utc_datetime": "2018-06-12T10:28:43.825Z",
    "percentage_complete": 100
  }
}

Some things to note:

  • Some properties, such as mbps and bytes_sec, are derived from other properties.
  • successes and failures don't really mean much on the download and upload tests.
  • utc_datetime is the time the test started: add the duration to get when the test finished.
  • duration is in microseconds
  • jitter is in microseconds
  • round_trip_time is the latency result in microseconds
  • The library does no rounding, leaving it completely up to the service consuming the data.

API options

You can pass options into the speed test by providing an object as the first argument to the SpeedTest constructor:

const st = new SpeedTest({
  global: {
    testServer: ['n1-the1.samknows.com', 'n2-the1.samknows.com', 'n3-the1.samknows.com'],
    licenceKey: 'YOUR-LICENCE-KEY'
  },
  download: {
    duration: 7000,
  },
});

The default options are as follows:

new SpeedTest({
  global: {
    targetsApi: '//speedtest-api.samknows.com/targets',
    targetSet: undefined,
    wsTestServerPort: 6501,
    fetchTestServerPort: 80,
    wsConcurrency: 8,
    fetchConcurrency: 8,
    warmupDuration: 2000,
    immediate: true,
    licenceKey: undefined
  },
  
  latency: {
    packets: 10,
  },
  
  download: {
    duration: 10000,
  
    startChunkSize: 16 * 1024,
    maxChunkSize: 1024 * 1024,
    maxChunkDuration: 1000,
  },
  
  upload: {
    duration: 10000,
  
    startChunkSize: 16 * 1024,
    maxChunkSize: 1024 * 1024,
    maxChunkDuration: 1000,
  },

  ingestion: {
    ingestionApi: 'https://ingestion-api.samknows.com',
    panelId: undefined,
  },
});

Each test looks at its own part of the object, then it looks at the global object if it isn't defined. For example, when the download test wants to know how long to run for, it looks at config.download.duration - it's defined, so it uses it. When it wants to know what server to test against, it looks at config.download.testServer, but that isn't defined so it uses config.global.testServer instead.

This means you can set configuration for all tests or configuration for individual tests depending on what your needs are.

You can override parts of the object or the whole object - the options you provide and the default options are merged using a deep merge strategy. Generally, most of the options can be left alone.

If you don't specify the testServer option (either a single server or an array of servers - the latency test will calculate which to test against), the speed test will call the SamKnows targets API to calculate the nearest test servers to test against. You can specify which target set to use using the targetSet option.

Licence agreement

Subject to the licence and terms agreed between SamKnows and the party.

2.0.9

1 year ago

2.0.8

1 year ago

2.0.5

3 years ago

2.0.7

3 years ago

2.0.6

3 years ago

2.0.4

3 years ago

2.0.3

3 years ago

2.0.2

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.8.0-next.0

3 years ago