home

JavaScript "ping" commentary

My ping page tests your network connection by sending requests / packets / queries / "hellos" / "pings" back to my web server and observing replies or lack thereof. The table headers are:

My page is a JavaScript (JS) / web equivalent of the networking "ping" command (ICMP echo, see WikiPedia "ping" entry).

I wrote a JS version of ping for use on a phone and other cases where one doesn't have a command prompt. (Yes, one can install a command prompt on a phone, but, for various reasons, even I haven't done that.)

The script reports timeout ("TO") after 10 seconds, or "ERR" (error).

"Seq" is the sending order (sequence number); aseq is the arrival sequence. If the packet is out of order, it shows an HTML table cell border.

Given my setup, average times of 30ms and 0 loss are good, with a maximum packet time under 60ms. I give detailed observations of ping numbers versus network quality below.

Code Documentation / Commentary

Seeing the code

You can see all of the code in most if not all desktop browsers with "View source" (control-U, command-U (I think)) or Chrome Developer Tools (control-shift-J).

You can also save my page, which should save the JavaScript, too. Then you can look at it all on your computer in Notepad (heaven forbid) or a much nicer Linux platform tool, or even much nicer proprietary-OS-platform tools.

High Level

I've rather prominently highlighted the JS references near the top of the ping page proper (HTML). I have a "view" JS file as in V in the MVC model, and a controller (C) / "business" logic file.

Details

Why I Look for responseText === 'OK'

I could almost certainly use a blank page or just about anything as a target for my HTTP request. I use a PHP script, though, so that I can run the script in "test mode" to simulate lost packets. If my script doesn't produce "OK," the JavaScript interprets this as an error / lost packet. Even if my PHP did "die()" or "exit(1)" without any explicit output, the PHP would still respond.

seq / timeout check

if (!this.trackera[seq] || this.trackera[seq].timeout) return;

Because "redo" resets the array but packets can still be outstanding, I have to check. I considered keeping a more-global sequence count (1 - 1,000 rather than recycling 1-20) so that I could cancel specific packets, but I seem to have found a better solution.

Also, on that line of code, I would assume a packet can return successfully an instant after it has timed out, but I'm not certain. In any event, I decide to ignore timed-out packets even if they do return.

2 getTime() calls before and after "send()"

On one hand, I need to set the start time before "send()" because it is theoretically possible for the packet to return before I set the start time on the line after "send()." It's called AJAX, Asynchronous..., for a reason.

On the other hand, if there is any delay between the actual packet send and the line after "send()", that is not a network issue and is not of interest to "ping." Maybe I should have an option to track both numbers and see how different they are.

Why the PEND_DELAY?

Because without that, there is a "flicker" of the pending count. It was annoying.

other processPacket() notes

I capture the time immediately upon entry because I don't want to introduce processing delays.

I have the option to "stop" the object because if I "redo" before all the packets have come back, "old" packets will process along with "new" packets. When that happened, it was very visually confusing.

Older Code Notes

i-- / reverse loop

When I was removing the previous individual packet entires, I went in reverse because if you go the other way, you'll really confuse JS either because of the way arrays work or because there is an underlying linked list or perhaps some other reason. I've had the some problem with PHP's DOM library.

My code read:
for (var i= table.childNodes.length - 1; i >= 0; i--) table.removeChild(table.childNodes[i]);

I later saw a better idea:
while(node.firstChild) node.removeChild(node.firstChild);

My current code has yet a better idea that seems to work. It only works because I separated out HTML "tbody."

Observed ping numbers versus network quality

My page / script pings my web server, Kwynn.com. Distance is of course a factor, so: Kwynn.com "lives" in northern Virginia, USA. See my specific location note below.

I believe it was this morning (2017/03/19) or else yesterday that I opened Kwynn.com so that anyone can ping it via ICMP / "real" ping. Thus, you can compare results of web ping versus "real" ping.

I'm near Atlanta, Georgia, USA. Right now (2017/03/19 9:00pm EDT) and for the last hour or so, my Comcast (Xfinity) network is working very well, and it is not under stress--no one on this household network is watching video. Via JS, I'm getting average pings of 30ms and no max pings above 60. My "real" ping average to Kwynn.com is only 4ms faster than web / JS ping.

Relative to your system, my numbers may be precise but not accurate--your average numbers may be higher or lower, but your numbers relative to that average should be meaningful. Otherwise put, the numbers won't be meaningful until you run the script a number of times under various conditions.

JS times will be at least slightly longer than ICMP times because JS uses TCP versus ICMP. Also, JS interpretation / processing itself is slower than a compiled "real" "ping" binary / executable.

When my network was in bad shape, one example was an average of 43ms (JS) with one outlier of 263ms. When I did ICMP ping against Kwynn.com, I got 15% packet loss, and Netflix wasn't working. GMail webmail worked, but it of course takes much less bandwidth. Other times during that period, JS ping showed times well over 1 full second, but, as I continued to sample, that was rare. More common were 1 - 3 packets over 200ms and the rest under 100.

Taking the past 3 days (03/17 - 19), here are my observations of both good conditions and bad. Even outliers over 200ms are probably a bad sign. However, ping and bandwidth are probably hard to correlate. Sometimes during bad conditions I'd get perfect JS ping numbers and 2% real-ping loss, but 1080 video would not work without numerous load delays. My video would not work in part because others on the home network were watching relatively low-res (480p / 720p?) video. When I went to Xfinity's bandwidth tester, I was only getting 10Mbps rather than 50 - 75. The other video was using all the house's bandwidth. Thus, a bandwidth test may sometimes be more obviously useful than ping.

Generally speaking, you should not lose any packets via either method. However, I have found that you may function on the net with 2% loss--webmail and very-low-res (360p) video, but, by 5%, you're likely to be having obvious problems. By 10 - 15%, you'll have very obvious problems.

AWS location

Kwynn.com is at the Amazon Web Services "us-east-1a" facility.

I already had reason to believe us-east-1a is near Ashburn, Virginia. I think I saw Ashburn in the "traceroute" command results at one point. Reporter Ingrid Burrington says the us-east-1 locations are probably in one or more of "Ashburn, Sterling, Haymarket, Manassas, [and] Chantilly" Virginia.

Works Cited

BURRINGTON, INGRID. "Why Amazon's Data Centers Are Hidden in Spy Country," The Atlantic (web site), 2016/01/08. Retrived 2017/03/19 8:25pm EDT.

The article looks very interesting with interesting works-cited of its own. However, I didn't read it all yet because I want to finish this page before next Tuesday.

Page History

Code History

after day n

Day n

Day 4

Gap

I'm pretty sure I made other changes.

Day 3

Day 2

Day 1

Page ID

ToFrHY9KxfV2

Check HTML validity of ping page

HTML5 valid