Speedtest worker now outputs status as JSON for easier parsing; Removed partial CSV implementation; Updated examples and documentation

This commit is contained in:
adolfintel 2018-08-08 08:57:24 +02:00
parent 0ce73a7e6c
commit 0954c6a6ac
14 changed files with 112 additions and 147 deletions

62
doc.md
View file

@ -1,7 +1,7 @@
# HTML5 Speedtest # HTML5 Speedtest
> by Federico Dossena > by Federico Dossena
> Version 4.6, August 7, 2018 > Version 4.6.1, August 8, 2018
> [https://github.com/adolfintel/speedtest/](https://github.com/adolfintel/speedtest/) > [https://github.com/adolfintel/speedtest/](https://github.com/adolfintel/speedtest/)
@ -107,18 +107,8 @@ we'll see the details of the format of the response.
```js ```js
w.onmessage = function (event) { w.onmessage = function (event) {
var data = event.data.split(';') var data = JSON.parse(event.data);
var testState = data[0] if (data.testState >= 4) {
var dlStatus = data[1]
var ulStatus = data[2]
var pingStatus = data[3]
var jitterStatus = data[5]
var clientIp = data[4]
var dlProgress = data[6]
var ulProgress = data[7]
var pingProgress = data[8]
var testId = data[9]
if (testState >= 4) {
clearInterval(timer) // test is finished or aborted clearInterval(timer) // test is finished or aborted
} }
// .. update your page here .. // .. update your page here ..
@ -126,12 +116,9 @@ w.onmessage = function (event) {
``` ```
#### Response format #### Response format
The response from the worker is composed of values separated by `;` (semicolon) in this The response from the worker is a JSON string containing these entries:
format:
`testState;dlStatus;ulStatus;pingStatus;clientIp;jitterStatus;dlProgress;ulProgress;pingProgress` * __testState__: an integer between -1 and 5
* __testState__ is an integer between -1 and 5
* `-1` = Test not started yet * `-1` = Test not started yet
* `0` = Test starting * `0` = Test starting
* `1` = Download test in progress * `1` = Download test in progress
@ -139,22 +126,22 @@ format:
* `3` = Upload test in progress * `3` = Upload test in progress
* `4` = Test finished * `4` = Test finished
* `5` = Test aborted * `5` = Test aborted
* __dlStatus__ is either * __dlStatus__: either
* Empty string (not started or aborted) * Empty string (not started or aborted)
* Download speed in Megabit/s as a number with 2 decimals * Download speed in Megabit/s as a number with 2 decimals
* The string "Fail" (test failed) * The string "Fail" (test failed)
* __ulStatus__ is either * __ulStatus__: either
* Empty string (not started or aborted) * Empty string (not started or aborted)
* Upload speed in Megabit/s as a number with 2 decimals * Upload speed in Megabit/s as a number with 2 decimals
* The string "Fail" (test failed) * The string "Fail" (test failed)
* __pingStatus__ is either * __pingStatus__: either
* Empty string (not started or aborted) * Empty string (not started or aborted)
* Estimated ping in milliseconds as a number with 2 decimals * Estimated ping in milliseconds as a number with 2 decimals
* The string "Fail" (test failed) * The string "Fail" (test failed)
* __clientIp__ is either * __clientIp__: either
* Empty string (not fetched yet or failed) * Empty string (not fetched yet or failed)
* The client's IP address as a string * The client's IP address as a string (with ISP info if enabled)
* __jitterStatus__ is either * __jitterStatus__: either
* Empty string (not started or aborted) * Empty string (not started or aborted)
* Estimated jitter in milliseconds as a number with 2 decimals (lower = stable connection) * Estimated jitter in milliseconds as a number with 2 decimals (lower = stable connection)
* The string "Fail" (test failed) * The string "Fail" (test failed)
@ -278,7 +265,11 @@ w.postMessage('start '+JSON.stringify(params))
* `1514 / 1460`: TCP+IPv4+ETH, ignoring HTTP overhead * `1514 / 1460`: TCP+IPv4+ETH, ignoring HTTP overhead
* `1514 / 1440`: TCP+IPv6+ETH, ignoring HTTP overhead * `1514 / 1440`: TCP+IPv6+ETH, ignoring HTTP overhead
* `1`: ignore overheads. This measures the speed at which you actually download and upload files rather than the raw connection speed * `1`: ignore overheads. This measures the speed at which you actually download and upload files rather than the raw connection speed
* __telemetry_extra__: Extra data that you want to be passed to the telemetry. This is a string field, if you want to pass an object, make sure you use ``JSON.stringify``. * __telemetry_level__: The type of telemetry to use. See the telemetry section for more info about this
* Default: `none`
* `basic`: send results only
* `full`: send results and debug info
* __telemetry_extra__: Extra data that you want to be passed to the telemetry. This is a string field, if you want to pass an object, make sure you use ``JSON.stringify``. This string will be added to the database entry for this test.
### Aborting the test prematurely ### Aborting the test prematurely
The test can be aborted at any time by sending an abort command to the worker: The test can be aborted at any time by sending an abort command to the worker:
@ -327,10 +318,10 @@ You need to start the test with your replacements like this:
w.postMessage('start {"url_dl": "newGarbageURL", "url_ul": "newEmptyURL", "url_ping": "newEmptyURL", "url_getIp": "newIpURL"}') w.postMessage('start {"url_dl": "newGarbageURL", "url_ul": "newEmptyURL", "url_ping": "newEmptyURL", "url_getIp": "newIpURL"}')
``` ```
## Telemetry ## Telemetry
Telemetry currently requires PHP and either MySQL, PostgreSQL or SQLite. Alternatively, it is possible to save to a CSV file. Telemetry currently requires PHP and either MySQL, PostgreSQL or SQLite.
To set up the telemetry, we need to do 4 things: To set up the telemetry, we need to do 4 things:
* copy the `telemetry` folder * copy the `telemetry` folder
* edit `telemetry_settings.php` to add your database or CSV settings * edit `telemetry_settings.php` to add your database settings
* create the database * create the database
* enable telemetry * enable telemetry
@ -341,7 +332,7 @@ If you see a table called `speedtest_users`, empty, you did it right.
### Configuring `telemetry.php` ### Configuring `telemetry.php`
Open `telemetry_settings.php` with notepad or a similar text editor. Open `telemetry_settings.php` with notepad or a similar text editor.
Set your preferred database, ``$db_type="mysql";``, ``$db_type="sqlite";``, ``$db_type="postgresql";`` or ``$db_type="csv";`` Set your preferred database, ``$db_type="mysql";``, ``$db_type="sqlite";`` or ``$db_type="postgresql";``
If you choose to use Sqlite3, you must set the path to your database file: If you choose to use Sqlite3, you must set the path to your database file:
```php ```php
$Sqlite_db_file = "../telemetry.sql"; $Sqlite_db_file = "../telemetry.sql";
@ -363,26 +354,19 @@ $PostgreSql_hostname="DB_HOSTNAME"; //database address, usually localhost
$PostgreSql_databasename="DB_NAME"; //the name of the database where you loaded telemetry_postgresql.sql $PostgreSql_databasename="DB_NAME"; //the name of the database where you loaded telemetry_postgresql.sql
``` ```
If you choose to use a CSV file, you must set the Csv_File and timezone variables.
```php
$Csv_File="myReportFile.csv";
$timezone='Europe/Paris';
```
__Note__: CSV currently only supports basic telemetry, the log will not be saved
### Enabling telemetry ### Enabling telemetry
Edit your test page; where you start the worker, you need to specify the `telemetry_level`. Edit your test page; where you start the worker, you need to specify the `telemetry_level`.
There are 3 levels: There are 3 levels:
* `none`: telemetry is disabled (default) * `none`: telemetry is disabled (default)
* `basic`: telemetry collects IP, ISP info, User Agent, Preferred language, Test results * `basic`: telemetry collects IP, ISP info, User Agent, Preferred language, Test results
* `full`: same as above, but also collects a log (10-150 Kb each, not recommended) * `full`: same as above, but also collects a debug log (10-150 Kb each, not recommended unless you're developing the speedtest)
Example: Example:
```js ```js
w.postMessage('start {"telemetry_level":"basic"}') w.postMessage('start {"telemetry_level":"basic"}')
``` ```
Also, see example-telemetry.html You can use example-telemetryEnabled.html and example-telemetry-resultSharing.html as starting points.
### Results sharing ### Results sharing
This feature generates an image that can be share by the user containing the download, upload, ping, jitter and ISP (if enabled). This feature generates an image that can be share by the user containing the download, upload, ping, jitter and ISP (if enabled).
@ -391,8 +375,6 @@ To use this feature, copy the `results` folder. You can customize the style of t
This feature requires Telemetry to be enabled, and FreeType2 must be installed in PHP (if not already be installed by your distro). This feature requires Telemetry to be enabled, and FreeType2 must be installed in PHP (if not already be installed by your distro).
__Note:__ CSV doesn't currently support this.
__Important:__ This feature relies on PHP functions `imagefttext` and `imageftbbox` that are well known for being problematic. The most common problem is that they can't find the font files and therefore nothing is drawn. This problem is metioned [here](http://php.net/manual/en/function.imagefttext.php) and was experienced by a lot of users. __Important:__ This feature relies on PHP functions `imagefttext` and `imageftbbox` that are well known for being problematic. The most common problem is that they can't find the font files and therefore nothing is drawn. This problem is metioned [here](http://php.net/manual/en/function.imagefttext.php) and was experienced by a lot of users.
### Seeing the results ### Seeing the results
@ -400,8 +382,6 @@ A basic front-end for visualizing and searching tests by ID is available in `tel
A login is required to access the interface. __Important__: change the default password in `telemetry_settings.php`. A login is required to access the interface. __Important__: change the default password in `telemetry_settings.php`.
__Note:__ CSV doesn't currently support this.
## Troubleshooting ## Troubleshooting
These are the most common issues reported by users, and how to fix them. If you still need help, contact me at [info@fdossena.com](mailto:info@fdossena.com). These are the most common issues reported by users, and how to fix them. If you still need help, contact me at [info@fdossena.com](mailto:info@fdossena.com).

View file

@ -24,11 +24,11 @@
var w = new Worker('speedtest_worker.min.js') // create new worker var w = new Worker('speedtest_worker.min.js') // create new worker
setInterval(function () { w.postMessage('status') }, 100) // ask for status every 100ms setInterval(function () { w.postMessage('status') }, 100) // ask for status every 100ms
w.onmessage = function (event) { // when status is received, split the string and put the values in the appropriate fields w.onmessage = function (event) { // when status is received, split the string and put the values in the appropriate fields
var data = event.data.split(';') // string format: status;download;upload;ping (speeds are in mbit/s) (status: 0=not started, 1=downloading, 2=uploading, 3=ping, 4=done, 5=aborted) var data = JSON.parse(event.data); //fetch speedtest worker output
document.getElementById('download').textContent = data[1] + ' Mbit/s' document.getElementById('download').textContent = data.dlStatus + ' Mbit/s'
document.getElementById('upload').textContent = data[2] + ' Mbit/s' document.getElementById('upload').textContent = data.ulStatus + ' Mbit/s'
document.getElementById('ping').textContent = data[3] + ' ms, ' + data[5] + ' ms jitter' document.getElementById('ping').textContent = data.pingStatus + ' ms, ' + data.jitterStatus + ' ms jitter'
document.getElementById('ip').textContent = data[4] document.getElementById('ip').textContent = data.clientIp
} }
w.postMessage('start') // start the speedtest (default params. keep garbage.php and empty.dat in the same directory as the js file) w.postMessage('start') // start the speedtest (default params. keep garbage.php and empty.dat in the same directory as the js file)
</script> </script>

View file

@ -200,8 +200,8 @@
w = new Worker('speedtest_worker.min.js') w = new Worker('speedtest_worker.min.js')
var interval = setInterval(function () { w.postMessage('status') }, 100) var interval = setInterval(function () { w.postMessage('status') }, 100)
w.onmessage = function (event) { w.onmessage = function (event) {
var data = event.data.split(';') var data = JSON.parse(event.data)
var status = Number(data[0]) var status = data.testStatus
if (status >= 4) { if (status >= 4) {
clearInterval(interval) clearInterval(interval)
document.getElementById('abortBtn').style.display = 'none' document.getElementById('abortBtn').style.display = 'none'
@ -211,24 +211,24 @@
if (status === 5) { if (status === 5) {
document.getElementById('testArea').style.display = 'none' document.getElementById('testArea').style.display = 'none'
} }
if (status === 1 && Number(data[1]) > 0) { if (status === 1 && Number(data.dlStatus) > 0) {
chart1.data.datasets[0].data[~~(20*Number(data[6]))]=(Number(data[1])) chart1.data.datasets[0].data[~~(20*Number(data.dlProgress))]=(Number(data.dlStatus))
chart1.data.labels[chart1.data.datasets[0].data.length - 1] = '' chart1.data.labels[chart1.data.datasets[0].data.length - 1] = ''
chart1.update() chart1.update()
} }
if (status === 3 && Number(data[2]) > 0) { if (status === 3 && Number(data.ulStatus) > 0) {
chart1.data.datasets[1].data[~~(20*Number(data[7]))]=(Number(data[2])) chart1.data.datasets[1].data[~~(20*Number(data.ulProgress))]=(Number(data.ulStatus))
chart1.data.labels[chart1.data.datasets[1].data.length - 1] = '' chart1.data.labels[chart1.data.datasets[1].data.length - 1] = ''
chart1.update() chart1.update()
} }
if (status === 2 && Number(data[3]) > 0) { if (status === 2 && Number(data.pingStatus) > 0) {
chart2.data.datasets[0].data.push(Number(data[3])) chart2.data.datasets[0].data.push(Number(data.pingStatus))
chart2.data.datasets[1].data.push(Number(data[5])) chart2.data.datasets[1].data.push(Number(data.jitterStatus))
chart2.data.labels[chart2.data.datasets[0].data.length - 1] = '' chart2.data.labels[chart2.data.datasets[0].data.length - 1] = ''
chart2.data.labels[chart2.data.datasets[1].data.length - 1] = '' chart2.data.labels[chart2.data.datasets[1].data.length - 1] = ''
chart2.update() chart2.update()
} }
ip.textContent = data[4] ip.textContent = data.clientIp
} }
w.postMessage('start') w.postMessage('start')
} }

View file

@ -131,18 +131,18 @@ function startStop(){
w.postMessage('start '+JSON.stringify(parameters)); //run the test with custom parameters w.postMessage('start '+JSON.stringify(parameters)); //run the test with custom parameters
I("startStopBtn").className="running"; I("startStopBtn").className="running";
w.onmessage=function(e){ w.onmessage=function(e){
var data=e.data.split(';'); var data=JSON.parse(e.data);
var status=Number(data[0]); var status=data.testStatus;
if(status>=4){ if(status>=4){
//test completed //test completed
I("startStopBtn").className=""; I("startStopBtn").className="";
w=null; w=null;
} }
I("ip").textContent=data[4]; I("ip").textContent=data.clientIp;
I("dlText").textContent=(status==1&&data[1]==0)?"...":data[1]; I("dlText").textContent=(status==1&&data.dlStatus==0)?"...":data.dlStatus;
I("ulText").textContent=(status==3&&data[2]==0)?"...":data[2]; I("ulText").textContent=(status==3&&data.ulStatus==0)?"...":data.ulStatus;
I("pingText").textContent=data[3]; I("pingText").textContent=data.pingStatus;
I("jitText").textContent=data[5]; I("jitText").textContent=data.jitterStatus;
}; };
} }
} }

View file

@ -125,15 +125,15 @@ function startStop(){
w.postMessage('start {"test_order":"D_U"}'); //run only download and upload tests, with a 1s pause in between w.postMessage('start {"test_order":"D_U"}'); //run only download and upload tests, with a 1s pause in between
I("startStopBtn").className="running"; I("startStopBtn").className="running";
w.onmessage=function(e){ w.onmessage=function(e){
var data=e.data.split(';'); var data=JSON.parse(e.data);
var status=Number(data[0]); var status=data.testStatus;
if(status>=4){ if(status>=4){
//test completed //test completed
I("startStopBtn").className=""; I("startStopBtn").className="";
w=null; w=null;
} }
I("dlText").textContent=(status==1&&data[1]==0)?"...":data[1]; I("dlText").textContent=(status==1&&data.dlStatus==0)?"...":data.dlStatus;
I("ulText").textContent=(status==3&&data[2]==0)?"...":data[2]; I("ulText").textContent=(status==3&&data.ulStatus==0)?"...":data.ulStatus;
}; };
} }
} }

View file

@ -163,8 +163,8 @@ function startStop(){
w.postMessage('start'); //Add optional parameters as a JSON object to this command w.postMessage('start'); //Add optional parameters as a JSON object to this command
I("startStopBtn").className="running"; I("startStopBtn").className="running";
w.onmessage=function(e){ w.onmessage=function(e){
data=e.data.split(';'); data=JSON.parse(e.data);
var status=Number(data[0]); var status=data.testStatus;
if(status>=4){ if(status>=4){
//test completed //test completed
I("startStopBtn").className=""; I("startStopBtn").className="";
@ -177,16 +177,16 @@ function startStop(){
//this function reads the data sent back by the worker and updates the UI //this function reads the data sent back by the worker and updates the UI
function updateUI(forced){ function updateUI(forced){
if(!forced&&(!data||!w)) return; if(!forced&&(!data||!w)) return;
var status=Number(data[0]); var status=data.testStatus;
I("ip").textContent=data[4]; I("ip").textContent=data.clientIp;
I("dlText").textContent=(status==1&&data[1]==0)?"...":data[1]; I("dlText").textContent=(status==1&&data.dlStatus==0)?"...":data.dlStatus;
drawMeter(I("dlMeter"),mbpsToAmount(Number(data[1]*(status==1?oscillate():1))),meterBk,dlColor,Number(data[6]),progColor); drawMeter(I("dlMeter"),mbpsToAmount(Number(data.dlStatus*(status==1?oscillate():1))),meterBk,dlColor,Number(data.dlProgress),progColor);
I("ulText").textContent=(status==3&&data[2]==0)?"...":data[2]; I("ulText").textContent=(status==3&&data.ulStatus==0)?"...":data.ulStatus;
drawMeter(I("ulMeter"),mbpsToAmount(Number(data[2]*(status==3?oscillate():1))),meterBk,ulColor,Number(data[7]),progColor); drawMeter(I("ulMeter"),mbpsToAmount(Number(data.ulStatus*(status==3?oscillate():1))),meterBk,ulColor,Number(data.ulProgress),progColor);
I("pingText").textContent=data[3]; I("pingText").textContent=data.pingStatus;
drawMeter(I("pingMeter"),msToAmount(Number(data[3]*(status==2?oscillate():1))),meterBk,pingColor,Number(data[8]),progColor); drawMeter(I("pingMeter"),msToAmount(Number(data.pingStatus*(status==2?oscillate():1))),meterBk,pingColor,Number(data.pingProgress),progColor);
I("jitText").textContent=data[5]; I("jitText").textContent=data.jitterStatus;
drawMeter(I("jitMeter"),msToAmount(Number(data[5]*(status==2?oscillate():1))),meterBk,jitColor,Number(data[8]),progColor); drawMeter(I("jitMeter"),msToAmount(Number(data.jitterStatus*(status==2?oscillate():1))),meterBk,jitColor,Number(data.pingProgress),progColor);
} }
function oscillate(){ function oscillate(){
return 1+0.02*Math.sin(Date.now()/100); return 1+0.02*Math.sin(Date.now()/100);

View file

@ -125,18 +125,18 @@ function startStop(){
w.postMessage('start'); //Add optional parameters as a JSON object to this command w.postMessage('start'); //Add optional parameters as a JSON object to this command
I("startStopBtn").className="running"; I("startStopBtn").className="running";
w.onmessage=function(e){ w.onmessage=function(e){
var data=e.data.split(';'); var data=JSON.parse(e.data);
var status=Number(data[0]); var status=data.testStatus;
if(status>=4){ if(status>=4){
//test completed //test completed
I("startStopBtn").className=""; I("startStopBtn").className="";
w=null; w=null;
} }
I("ip").textContent=data[4]; I("ip").textContent=data.clientIp;
I("dlText").textContent=(status==1&&data[1]==0)?"...":data[1]; I("dlText").textContent=(status==1&&data.dlStatus==0)?"...":data.dlStatus;
I("ulText").textContent=(status==3&&data[2]==0)?"...":data[2]; I("ulText").textContent=(status==3&&data.ulStatus==0)?"...":data.ulStatus;
I("pingText").textContent=data[3]; I("pingText").textContent=data.pingStatus;
I("jitText").textContent=data[5]; I("jitText").textContent=data.jitterStatus;
}; };
} }
} }

View file

@ -143,19 +143,19 @@ function startStop(){
w.postMessage('start'); //Add optional parameters as a JSON object to this command w.postMessage('start'); //Add optional parameters as a JSON object to this command
I("startStopBtn").className="running"; I("startStopBtn").className="running";
w.onmessage=function(e){ w.onmessage=function(e){
var data=e.data.split(';'); var data=JSON.parse(e.data);
var status=Number(data[0]); var status=data.testStatus;
if(status>=4){ if(status>=4){
//test completed //test completed
I("startStopBtn").className=""; I("startStopBtn").className="";
w=null; w=null;
} }
I("ip").textContent=data[4]; I("ip").textContent=data.clientIp;
I("dlText").textContent=(status==1&&data[1]==0)?"...":data[1]; I("dlText").textContent=(status==1&&data.dlStatus==0)?"...":data.dlStatus;
I("ulText").textContent=(status==3&&data[2]==0)?"...":data[2]; I("ulText").textContent=(status==3&&data.ulStatus==0)?"...":data.ulStatus;
I("pingText").textContent=data[3]; I("pingText").textContent=data.pingStatus;
I("jitText").textContent=data[5]; I("jitText").textContent=data.jitterStatus;
var prog=(Number(data[6])*2+Number(data[7])*2+Number(data[8]))/5; var prog=(Number(data.dlProgress)*2+Number(data.ulProgress)*2+Number(data.pingProgress))/5;
I("progress").style.width=(100*prog)+"%"; I("progress").style.width=(100*prog)+"%";
}; };
} }

View file

@ -180,8 +180,8 @@ function startStop(){
I("startStopBtn").className="running"; I("startStopBtn").className="running";
I("shareArea").style.display="none"; I("shareArea").style.display="none";
w.onmessage=function(e){ w.onmessage=function(e){
data=e.data.split(';'); data=JSON.parse(e.data);
var status=Number(data[0]); var status=data.testStatus;
if(status>=4){ if(status>=4){
//test completed //test completed
I("startStopBtn").className=""; I("startStopBtn").className="";
@ -190,7 +190,7 @@ function startStop(){
if(status==4){ if(status==4){
//if testId is present, show sharing panel, otherwise do nothing //if testId is present, show sharing panel, otherwise do nothing
try{ try{
var testId=Number(data[9]); var testId=Number(data.testId);
if(!isNaN(testId)){ if(!isNaN(testId)){
var shareURL=window.location.href.substring(0,window.location.href.lastIndexOf("/"))+"/results/?id="+testId; var shareURL=window.location.href.substring(0,window.location.href.lastIndexOf("/"))+"/results/?id="+testId;
I("resultsImg").src=shareURL; I("resultsImg").src=shareURL;
@ -207,16 +207,16 @@ function startStop(){
//this function reads the data sent back by the worker and updates the UI //this function reads the data sent back by the worker and updates the UI
function updateUI(forced){ function updateUI(forced){
if(!forced&&(!data||!w)) return; if(!forced&&(!data||!w)) return;
var status=Number(data[0]); var status=data.testStatus;
I("ip").textContent=data[4]; I("ip").textContent=data.clientIp;
I("dlText").textContent=(status==1&&data[1]==0)?"...":data[1]; I("dlText").textContent=(status==1&&data.dlStatus==0)?"...":data.dlStatus;
drawMeter(I("dlMeter"),mbpsToAmount(Number(data[1]*(status==1?oscillate():1))),meterBk,dlColor,Number(data[6]),progColor); drawMeter(I("dlMeter"),mbpsToAmount(Number(data.dlStatus*(status==1?oscillate():1))),meterBk,dlColor,Number(data.dlProgress),progColor);
I("ulText").textContent=(status==3&&data[2]==0)?"...":data[2]; I("ulText").textContent=(status==3&&data.ulStatus==0)?"...":data.ulStatus;
drawMeter(I("ulMeter"),mbpsToAmount(Number(data[2]*(status==3?oscillate():1))),meterBk,ulColor,Number(data[7]),progColor); drawMeter(I("ulMeter"),mbpsToAmount(Number(data.ulStatus*(status==3?oscillate():1))),meterBk,ulColor,Number(data.ulProgress),progColor);
I("pingText").textContent=data[3]; I("pingText").textContent=data.pingStatus;
drawMeter(I("pingMeter"),msToAmount(Number(data[3]*(status==2?oscillate():1))),meterBk,pingColor,Number(data[8]),progColor); drawMeter(I("pingMeter"),msToAmount(Number(data.pingStatus*(status==2?oscillate():1))),meterBk,pingColor,Number(data.pingProgress),progColor);
I("jitText").textContent=data[5]; I("jitText").textContent=data.jitterStatus;
drawMeter(I("jitMeter"),msToAmount(Number(data[5]*(status==2?oscillate():1))),meterBk,jitColor,Number(data[8]),progColor); drawMeter(I("jitMeter"),msToAmount(Number(data.jitterStatus*(status==2?oscillate():1))),meterBk,jitColor,Number(data.pingProgress),progColor);
} }
function oscillate(){ function oscillate(){
return 1+0.02*Math.sin(Date.now()/100); return 1+0.02*Math.sin(Date.now()/100);

View file

@ -125,18 +125,18 @@ function startStop(){
w.postMessage('start {"telemetry_level":"basic"}'); //Add optional parameters (see doc.md) w.postMessage('start {"telemetry_level":"basic"}'); //Add optional parameters (see doc.md)
I("startStopBtn").className="running"; I("startStopBtn").className="running";
w.onmessage=function(e){ w.onmessage=function(e){
var data=e.data.split(';'); var data=JSON.parse(e.data);
var status=Number(data[0]); var status=data.testStatus
if(status>=4){ if(status>=4){
//test completed //test completed
I("startStopBtn").className=""; I("startStopBtn").className="";
w=null; w=null;
} }
I("ip").textContent=data[4]; I("ip").textContent=data.clientIp;
I("dlText").textContent=(status==1&&data[1]==0)?"...":data[1]; I("dlText").textContent=(status==1&&data.dlStatus==0)?"...":data.dlStatus;
I("ulText").textContent=(status==3&&data[2]==0)?"...":data[2]; I("ulText").textContent=(status==3&&data.ulStatus==0)?"...":data.ulStatus;
I("pingText").textContent=data[3]; I("pingText").textContent=data.pingStatus;
I("jitText").textContent=data[5]; I("jitText").textContent=data.jitterStatus;
}; };
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
HTML5 Speedtest v4.6 HTML5 Speedtest v4.6.1
by Federico Dossena by Federico Dossena
https://github.com/adolfintel/speedtest/ https://github.com/adolfintel/speedtest/
GNU LGPLv3 License GNU LGPLv3 License
@ -63,7 +63,7 @@ function url_sep (url) { return url.match(/\?/) ? '&' : '?'; }
/* /*
listener for commands from main thread to this worker. listener for commands from main thread to this worker.
commands: commands:
-status: returns the current status as a string of values spearated by a semicolon (;) in this order: testStatus;dlStatus;ulStatus;pingStatus;clientIp;jitterStatus;dlProgress;ulProgress;pingProgress -status: returns the current status as a JSON string containing testStatus, dlStatus, ulStatus, pingStatus, clientIp, jitterStatus, dlProgress, ulProgress, pingProgress
-abort: aborts the current test -abort: aborts the current test
-start: starts the test. optionally, settings can be passed as JSON. -start: starts the test. optionally, settings can be passed as JSON.
example: start {"time_ul":"10", "time_dl":"10", "count_ping":"50"} example: start {"time_ul":"10", "time_dl":"10", "count_ping":"50"}
@ -71,7 +71,18 @@ function url_sep (url) { return url.match(/\?/) ? '&' : '?'; }
this.addEventListener('message', function (e) { this.addEventListener('message', function (e) {
var params = e.data.split(' ') var params = e.data.split(' ')
if (params[0] === 'status') { // return status if (params[0] === 'status') { // return status
postMessage(testStatus + ';' + dlStatus + ';' + ulStatus + ';' + pingStatus + ';' + clientIp + ';' + jitterStatus + ';' + dlProgress + ';' + ulProgress + ';' + pingProgress+ ';' + testId) postMessage(JSON.stringify({
testStatus:testStatus,
dlStatus:dlStatus,
ulStatus:ulStatus,
pingStatus:pingStatus,
clientIp:clientIp,
jitterStatus:jitterStatus,
dlProgress:dlProgress,
ulProgress:ulProgress,
pingProgress:pingProgress,
testId:testId
}))
} }
if (params[0] === 'start' && testStatus === -1) { // start new test if (params[0] === 'start' && testStatus === -1) { // start new test
testStatus = 0 testStatus = 0

File diff suppressed because one or more lines are too long

View file

@ -56,26 +56,5 @@ if($db_type=="mysql"){
echo "id ".$conn->lastInsertId(); echo "id ".$conn->lastInsertId();
$conn = null; $conn = null;
} }
elseif($db_type=="csv"){ else die("-1");
// Prepare the csv formatted string
date_default_timezone_set($timezone);
$date = date('Y-m-d H:i:s');
$str = '"' . $date . '",';
$str .= '"' . $ip . '",';
$str .= '"' . $ispinfo . '",';
$str .= '"' . $ua . '",';
$str .= '"' . $dl . '",';
$str .= '"' . $ul . '",';
$str .= '"' . $ping . '",';
$str .= '"' . $jitter . '"' . "\n";
// Set header if this is a new file
if (!file_exists($Csv_File)) {
$header = '"date","ip","ispinfo","ua","download","upload","ping","jitter"' . "\n";
file_put_contents($Csv_File, $header, FILE_APPEND);
}
// Write line to file
file_put_contents($Csv_File, $str, FILE_APPEND);
}
?> ?>

View file

@ -1,6 +1,6 @@
<?php <?php
$db_type="mysql"; //Type of db: "mysql", "sqlite", "postgresql" or "csv" $db_type="mysql"; //Type of db: "mysql", "sqlite" or "postgresql"
$stats_password="PASSWORD"; //password to login to stats.php. Change this!!! $stats_password="PASSWORD"; //password to login to stats.php. Change this!!!
// Sqlite3 settings // Sqlite3 settings
@ -18,11 +18,6 @@ $PostgreSql_password="PASSWORD";
$PostgreSql_hostname="DB_HOSTNAME"; $PostgreSql_hostname="DB_HOSTNAME";
$PostgreSql_databasename="DB_NAME"; $PostgreSql_databasename="DB_NAME";
// CSV settings
$Csv_File="../../reports.csv";
$timezone='UTC';
//IMPORTANT: DO NOT ADD ANYTHING BELOW THIS PHP CLOSING TAG, NOT EVEN EMPTY LINES!
//IMPORTANT: DO NOT ADD ANYTHING BELOW THIS PHP CLOSING TAGS, NOT EVEN EMPTY LINES!
?> ?>