JavaScript: Creating an EventSource within a Worker

After spending the day finishing out cross-browser EventSource support in the form of jQuery.EventSource.js, then wrapping up with a commit of 55 new unit tests, I finally left the Bocoup Loft for the day around 8 o’clock… But as most developers know, no matter how hard you try, you just can’t leave this kind of work at the office. On the short ride home I had some time to reflect on the developments of modern browsers and how exciting things like Workers, SharedWorkers and EventSource are…

… And that’s when it occurred to me… Could it be possible that when the Chromium crew implemented the EventSource API, that they extended the interface across processes so that both the renderer and worker processes had access to the constructor?

After taking Alli the Dog for a quick walk, I spun together this demo…

Some HTML to facilitate running the test in a browser:

renderer.html

<script src="renderer.js"></script>

The contents of renderer.js; this will create the worker object and then send a quick dummy message out to it.

renderer.js

var worker  = new Worker('worker.js');

worker.addEventListener('message', function (event) {
  var message = event.data;

  console.group('Message Received');
  console.log( message );
  console.groupEnd();

}, false);

//  This will trigger a message event in the worker
worker.postMessage(true);

The contents of worker.js; this will receive the dummy message, declare a new EventSource and start listening to it.

worker.js

self.addEventListener('message', function (event) {
  var thisp     = this,
      eventSrc  = new EventSource('event-source.php');

  eventSrc.addEventListener('message', function (event) {

    var message = JSON.parse(event.data);

    thisp.postMessage(message);

  }, false);
}, false);

The contents of event-source.php; this simply sends a modified text/event-stream header then echoes a small json fragment, prepended with the ‘data; ‘ tag:

event-source.php

<?php
header("Content-Type: text/event-stream\n\n");

echo 'data: ' . json_encode(
                  array(
                    'from' => 'event-source'
                  )
                ) . "\n";
?>

… So what was the result? While I wrote this, I ran the demo in another tab and at this moment 355 EventSource messages were received by the Worker, which in turn sent 355 messages back to the renderer (client/browser) which then logged them to the javascript console.

It’s not much, but it’s proof that it can be done – bear in mind that only the WebKit browsers support EventSource, therefore this will only work in either Chrome 5+ or Safari 5+.

Download the demo files from Github

Comments

We moved off of Disqus for data privacy and consent concerns, and are currently searching for a new commenting tool.

  1. just found this article, and wow, this was in my mind. so its now\u00a0 2012, do the real browsers support this?

    im going to try this, i have to wow them at work 🙁

  2. This is a great article. I am trying to so that same thing but I can’t seems to get this to work. I keep getting ReferenceError: EventSource is not defined int he console. Any idea why is that? I copied you code over including the PHP code to see if i can get it to work. Thank you for your help

Contact Us

We'd love to hear from you. Get in touch!

Mail

P.O. Box 961436
Boston, MA 02196