(done)
| 586 | // ping+jitter test, function done is called when it's over |
| 587 | let ptCalled = false; // used to prevent multiple accidental calls to pingTest |
| 588 | function pingTest(done) { |
| 589 | tverb("pingTest"); |
| 590 | if (ptCalled) return; |
| 591 | else ptCalled = true; // pingTest already called? |
| 592 | const startT = new Date().getTime(); //when the test was started |
| 593 | let prevT = null; // last time a pong was received |
| 594 | let ping = 0.0; // current ping value |
| 595 | let jitter = 0.0; // current jitter value |
| 596 | let i = 0; // counter of pongs received |
| 597 | let prevInstspd = 0; // last ping time, used for jitter calculation |
| 598 | xhr = []; |
| 599 | // ping function |
| 600 | const doPing = function() { |
| 601 | tverb("ping"); |
| 602 | pingProgress = i / settings.count_ping; |
| 603 | prevT = new Date().getTime(); |
| 604 | xhr[0] = new XMLHttpRequest(); |
| 605 | xhr[0].onload = function() { |
| 606 | // pong |
| 607 | tverb("pong"); |
| 608 | if (i === 0) { |
| 609 | prevT = new Date().getTime(); // first pong |
| 610 | } else { |
| 611 | let instspd = new Date().getTime() - prevT; |
| 612 | if (settings.ping_allowPerformanceApi) { |
| 613 | try { |
| 614 | //try to get accurate performance timing using performance api |
| 615 | let p = performance.getEntries(); |
| 616 | p = p[p.length - 1]; |
| 617 | let d = p.responseStart - p.requestStart; |
| 618 | if (d <= 0) d = p.duration; |
| 619 | if (d > 0 && d < instspd) instspd = d; |
| 620 | } catch (e) { |
| 621 | //if not possible, keep the estimate |
| 622 | tverb("Performance API not supported, using estimate"); |
| 623 | } |
| 624 | } |
| 625 | //noticed that some browsers randomly have 0ms ping |
| 626 | if (instspd < 1) instspd = prevInstspd; |
| 627 | if (instspd < 1) instspd = 1; |
| 628 | const instjitter = Math.abs(instspd - prevInstspd); |
| 629 | if (i === 1) ping = instspd; |
| 630 | /* first ping, can't tell jitter yet*/ else { |
| 631 | if (instspd < ping) ping = instspd; // update ping, if the instant ping is lower |
| 632 | if (i === 2) jitter = instjitter; |
| 633 | //discard the first jitter measurement because it might be much higher than it should be |
| 634 | else jitter = instjitter > jitter ? jitter * 0.3 + instjitter * 0.7 : jitter * 0.8 + instjitter * 0.2; // update jitter, weighted average. spikes in ping values are given more weight. |
| 635 | } |
| 636 | prevInstspd = instspd; |
| 637 | } |
| 638 | pingStatus = ping.toFixed(2); |
| 639 | jitterStatus = jitter.toFixed(2); |
| 640 | i++; |
| 641 | tverb("ping: " + pingStatus + " jitter: " + jitterStatus); |
| 642 | if (i < settings.count_ping) doPing(); |
| 643 | else { |
| 644 | // more pings to do? |
| 645 | pingProgress = 1; |
no test coverage detected