Archive

Archive for the ‘Web Development’ Category

AJAX Based Bandwidth Test

At work, I was tasked to add auto-playing Flash video feeds on the home page of one of our web sites, and I decided that before I do anything I should implement a quick AJAX-driven bandwidth check so that dial-up users aren’t fed a heavy video feed without prior user consent. I threw the test together in a matter of three or four hours, and sent the engineering team an e-mail letting them know that this is new working functionality we can use any time.

The funny thing about the timing is that on the same day another co-worker working on another web site needed the same functionality immediately. To be honest, I overheard talk about this, and so I hoped my contribution would be useful for that project as well. I have no doubt my co-worker could have accomplished the same task, but being able to drop off sharable solutions like this is part of what makes a team environment so valuable.

 

The Bandwidth Test: What It Is and How it Works

The functionality I’m referring to here is a bandwidth test using AJAX.

Actually, truth be told, it’s not all-out AJAX as there is no XML in use here, but there is an asynchronous Javascript-driven HTTP request for a string of bytes, and a measurement of the amount of time that took. Actually, there are two asychronous HTTP requests. The first request is for a single byte of data–this measures latency and HTTP overhead. The second request is for a larger set of bytes of data, i.e. 128KB, which is configurable as a control property. The amount of time taken for the first request (1B) is subtracted from the amount of time taken from the second request (128KB), and this measures Pipe Speed. The requests are both sent to a "callback" URL that you can configure, but by default it’s an .aspx file stored as "~/controls_callback/GenBytes.aspx?len=number_of_bytes".

(Please excuse the horribly crappy illustration — I had to use Paint.NET as I don’t have Adobe Illustrator installed on my laptop, and then on top of that Live Writer and/or Live Spaces does weird things to the image. Click to enlarge.)

The test is not intended to be exact, but to be an approximation to determine whether your connection is moderately fast or dog slow. But the accuracy of the test gets better the slower the connection is, so a slow connection–which comprises the more vulnerable web audience–will be less likely to have incorrect test results than a higher speed user.

The test is implemented on a site by adding a small, simple ASP.NET tag:

(Add to top of .aspx file:)
<%@ Register Src="~/controls/SpeedTest.ascx" TagPrefix="ajax" TagName="SpeedTest" %>

..

<ajax:SpeedTest runat="server" ExecuteTest="true" UseCookie="false" ClientCompleteFunction="myJavascriptFunction" />

The control automatically registers a block of Javascript to the containing Page. ExecuteTest="true" is the default setting–if you do not include this attribute, the test will execute, but setting it to False will result in no Javascript being added to the page at all. Why would the tag still be useful? Setting UseCookie="true" will add the test results to the cookie ("astLatency" and "astPipeSpeed") and will expose these values as properties. (If the cookies are already set and UseCookies is true, the test won’t execute anyway.) You might choose to execute the test on one page and then redirect (ExecuteTest="true"), and only read the resulting cookie on another page (ExecuteTest="false"). But if the first hit can make a safe, untested assumption — the test is asynchronous, after all — then you might as well just put the control on your content page, turn on the test, and set ExecuteTest="false" on the next hit from the same visitor, when the cookie has been set.

Properties:

ExecuteTest (gets/sets bool) true = Adds test script which auto-executes.
false = Doesn’t do anything client-side.
UseCookies (gets/sets bool) true = Disables test execution if the Request already has the assigned cookie.
false = Doesn’t evaluate cookies.
CookieExpires (gets/sets TimeSpan) TimeSpan in granularity of days to retain the cookie if UseCookies == true.
CookieLatency (gets/sets int?) Nullable<Int32> of the cookie value astLatency.
CookiePipeSpeed (gets/sets int?) Nullable<Int32> of the cookie value astPipeSpeed.
ClientCompleteFunction (gets/sets string) The name of your own Javascript function that executes when the test is complete. The function should accept two parameters: latency and pipeSpeed.
CallBackUrl (gets/sets string) The URL of the support .aspx file that dynamically generates bytes of a requested length.
ByteLength (gets/sets int) The number of bytes to be requested from the CallBackUrl.

You can download the whole thing and examine the Javascript in the control file (SpeedTest.ascx) here…

Download: http://www.jondavis.net/CodeProjects/SpeedCheck/SpeedCheck.zip

Demo (from a slow cable connection as host): http://www.jondavis.net/CodeProjects/SpeedCheck/SpeedTest.aspx

Categories: Web Development

Question of the Day: How do you scale out the server load of a web site to multiple IIS hosts to improve performance?

If anyone out there is reading this, make your comments known, I will update this post tomorrow. If you’re viewing an RSS feed, follow the article URL.

Categories: Web Development