Yesterday I started a series of blog posts on HTML5 apps oriented architectures. You can read the first post HERE.

The demo lets the user select a video that they want to watch and then, when the click on the link, the code dynamically download’s that video and plays it for the user. The next logical step for the evolution of the demo is to move the video download logic out of the main thread using HTML5 Web Workers.

On it’s own, moving the download to another thread doesn’t buy us much. There is nothing for the user to do while they are waiting for the first video to download and subsequent download requests don’t interrupt the video player until they are finished.

But, I’m looking forward to how I want the down feature to ultimately work. Ultimately, I want to store any downloaded videos in a data base and let the user watch saved videos while downloading new videos. That means I’ll need a mechanism by which the user can add videos to a download queue in a Web Worker.

So I spent time today looking into how web workers function. I found lots of demos but I didn’t find one that I thought was a really straight forward test. So I wrote one.

The test model is simple and you’ve probably seen this oversize when learning web services.

We’ll create a Web Worker with a method that receives an argument. The Web Worker will add some text to the inbound argument and return the combined string.

Lets first look at what the running app and then we’ll review the code.

Web Worker Sample

When I click on the “Send to Worker” button, the button click event handler sends the string “MisfitGeek” to a method in the worker process. The worker process appends some text and returns the newly combined string.

Web Worker Demo - Return

Note the number in square brackets at the end of the string in the alert box. It’s value is “1”.

If I click on “OK” and then click on the “Send to Worker” button again, that numeric value changes,

Web Worker Demo - Return

Now let’s look at the code.

The code for the Web Worker lives in a JavaScript code file named “worker.js”.

Here is the code: (It’s just 6 lines long.)


var callCount = 0;

self.onmessage = function(event) {
  callCount++;
  // Below is a single line of code seperated for display purposes.
  self.postMessage(event.data +
                   ' : Hello from your worker ! [' + callCount + ']');
};

The code doesn’t do all that much. It increments the local variable “callCount” and then creates and returns a string by combining the string parameter that was passed in with local values.

The calling page looks like this.



<script type="text/javascript">// <![CDATA[
        var worker = new Worker('js/worker.js');
        worker.addEventListener('message', function(event) {
         alert(event.data);
        }, false);

        function callWorker(msg) {
           worker.postMessage(msg); // start the worker.
	    }

// ]]></script>
    HTML5 Example - Worker
</pre>
<div id="mainDiv" style="text-align: center;">
  <button onclick="callWorker('MisfitGeek')">
    Send to Worker.
  </button>
 These aren't the droids you're looking for.
 - Move along... move along.</div>
<pre>


Lines #5 and #6 above are where the magic happens.

Line #5 says take the code in worker.js and run it in a Web Worker.

Line #6 says to hook up the following anonymous function for when that worker posts a message. In our case all we are going to do in that funtion ios to use the message send to the main thread from the Web Worker to display in an alert dialogue.

Line #10 declares a local function that will be called when the user clicks on the “Send to Worker” button which will be called with a text argument (in our case this is hard coded to the text “MisfitGeek”. That function call sthe Web Worker postMessage() method, sending as an argument the text (“MisfitGeek”).

Not that the variable callCount defined in worker.js is not accessible outside the Web Worker.

Simple but powerful. We will use this method in a future post to download video files as selected without blocking the user interface !