SharedWorker simple test case?

923 views
Skip to first unread message

rektide

unread,
Feb 22, 2010, 11:34:56 PM2/22/10
to Chromium HTML5
I'm trying to use SharedWorkers, but not getting anywhere. I whipped
up a quick demoscript where a page "ping"s a SharedWorker and the
SharedWorker should "pong" back, but something isnt working, and I
have no idea what. The code is running at http://rektide.voodoowarez.com/2010/2/ping.html
. Its also pasted below:

ping.html:
<html>
<head><title>PingPong SharedWorker</title></head>
<body>

<script type="text/javascript">
var worker = new SharedWorker("pong.js",'pingpong')
worker.onerror = function(err) {
document.write("[problem "+err+"]")
}

var count = 4;
worker.port.addEventListener('message', function(e) {
document.write("[data: "+e.data+"]")
if(--count)
worker.port.postMessage("ping")
},false)

worker.port.postMessage("ping")
</script>

begin<br/>

</body>
</html>


pong.js:

var messageHandler = function(event) {
event.ports[0].postMessage("pong")
};

onconnect = function(event) {
event.ports[0].onmessage = messageHandler
event.ports[0].postMessaage("connect")
};


Please help me use this incredible feature. I have no idea what I'm
doing wrong.
-rektide

Drew Wilson

unread,
Feb 23, 2010, 2:12:44 PM2/23/10
to rektide, Chromium HTML5
First off, I'm really happy to see developers starting to use SharedWorkers! I'm sorry you ran into problems, but the debugger support for SharedWorkers is still a work in progress.

Anyhow, there are several issues, most of which are fairly non-obvious/obscure, so don't feel bad for stubbing your toe on them - I've run into every single one of these myself at one time or another:

1) Your onconnect handler in pong.js has a typo:

       event.ports[0].postMessaage("connect")

Note the double "a" in postMessaage(). It turns out that parse exceptions generated within workers are not always logged to the developers console, which makes errors like this really hard to track down. I've logged bug http://code.google.com/p/chromium/issues/detail?id=36577 to track this issue.

2) The messageHandler function won't work, because MessageEvent won't have event.ports[0] set.

MessageEvent has its "ports" attribute set to the set of ports that were passed to postMessage() (http://www.w3.org/TR/html5/comms.html#dom-messageevent-ports). You are expecting it to be set to the port that sent the message, which isn't the case. The onmessage handler is not passed a reference to the entangled port - what you need to do is keep a reference around to the source port sent to you in the onconnect handler. The way I usually do this is via a closure:

var messageHandler = function(event, port) {
       port.postMessage("pong")
};

onconnect = function(event) {
       event.ports[0].onmessage = function(e) { messageHandler(e, event.ports[0]); };
       event.ports[0].postMessage("connect");
};

3) A MessagePort will not deliver onmessage events until you call start() on it. So if you just use addEventListener("message", function...), your function won't be called until you call port.start(). If you register an event listener by setting the onmessage attribute directly, then it starts the port for you. Yes, it's very confusing (http://www.w3.org/TR/html5/comms.html#messageport) but the intent is to make sure that ports don't dispatch events until the listener has been added. I never use addEventListener() for exactly this reason but instead directly set the onmessage attribute.

So, this should work:

ping.html:
<html>
<head><title>PingPong SharedWorker</title></head>
<body>
<div id=result></div>
<script type="text/javascript">
function log(message)
{
  document.getElementById("result").innerHTML += message + "<br>";
}

var worker = new SharedWorker("pong.js",'pingpong')
worker.onerror = function(err) {
       log("[problem "+err+"]")
}

var count = 4;
worker.port.addEventListener('message', function(e) {
       log("[data: "+e.data+"]")
       if(--count)
           worker.port.postMessage("ping")
},false);
worker.port.start();
log("begin");
</script>



</body>
</html>



pong.js:

onconnect = function(event) {
       event.ports[0].onmessage = function(e) { event.ports[0].postMessage("pong"); };
       event.ports[0].postMessage("connect")
};

-atw


--
You received this message because you are subscribed to the Google Groups "Chromium HTML5" group.
To post to this group, send email to chromiu...@chromium.org.
To unsubscribe from this group, send email to chromium-html...@chromium.org.
For more options, visit this group at http://groups.google.com/a/chromium.org/group/chromium-html5/?hl=en.


Drew Wilson

unread,
Feb 23, 2010, 4:27:37 PM2/23/10
to rektide, Chromium HTML5, Dmitry Titov
Following up on this - for #2, I believe that MessageEvent.target == the port. So your messageHandler() function could be:

messageHandler = function(event) {
  event.target.postMessage("pong");
}

You don't have to use a closure.

-atw

Ivan Zuzak

unread,
Feb 27, 2010, 6:50:03 AM2/27/10
to Chromium HTML5
Hi Drew,

I tried your example in some older build of Chromium I had installed
(around 39330) and it was working nicely. However, the example from
Simon Peters on the WHATWG mailing list [1] was crashing - Chromium
showed an exception that a HTML SharedWorker crashed (in the yellow
notification bar below the bookmarks bar, nothing was alerted in the
console). That example differs from this one in basically one thing -
the shared worker is instantiated in two places (in a window context
and in a child iframe context). Notice, however, that the workers are
not given a name in Simon's example. Anyway - the Chromium version I
had installed crashed when a SharedWorker was created in both contexts
from the same JavaScript source, but worked fine when created in only
one context (no matter which one).

Hoping that it was a bug which had been resolved in never versions, I
did an update of Chromium and am now running 40217. However, now I
can't even get your example running (which, as I said, worked in the
older version). No exceptions are thrown, but from what I can tell -
Chromium breaks when instantiating a SharedWorker. Did anything
SharedWorker-wise change in the last ~800 versions that would cause
the example to stop working? Possibly helpful debugging info: windows
xp OS and I'm running the example from the local filesystem, they're
not online. Any ideas? :)

I think Workers and SharedWorkers are awesome and can't wait to see
all the cool things people will be doing with them. That's one reason
why I developed the pmrpc library [2] which is essentially a RPC
mechanism built on top of cross-document messaging APIs (for inter-
window/iframe communication) and web workers (for communication
between workers and windows/iframes). The library currently supports
regular Workers but has been waiting on a full SharedWorker
implementation in Chromium so I can test, debug and rejoice :).

Thanks,
Ivan

[1] http://www.mail-archive.com/wha...@lists.whatwg.org/msg20329.html
[2] http://code.google.com/p/pmrpc/

On Feb 23, 10:27 pm, Drew Wilson <atwil...@chromium.org> wrote:
> Following up on this - for #2, I believe that MessageEvent.target == the
> port. So your messageHandler() function could be:
>
> messageHandler = function(event) {
>   event.target.postMessage("pong");
>
> }
>
> You don't have to use a closure.
>
> -atw
>
>
>
> On Tue, Feb 23, 2010 at 11:12 AM, Drew Wilson <atwil...@chromium.org> wrote:
> > First off, I'm really happy to see developers starting to use
> > SharedWorkers! I'm sorry you ran into problems, but the debugger support for
> > SharedWorkers is still a work in progress.
>
> > Anyhow, there are several issues, most of which are fairly
> > non-obvious/obscure, so don't feel bad for stubbing your toe on them - I've
> > run into every single one of these myself at one time or another:
>
> > 1) Your onconnect handler in pong.js has a typo:
>

> >        event.ports[0].postMess*aa*ge("connect")


>
> > Note the double "a" in postMessaage(). It turns out that parse exceptions
> > generated within workers are not always logged to the developers console,
> > which makes errors like this really hard to track down. I've logged bug

> >http://code.google.com/p/chromium/issues/detail?id=36577to track this

> > *worker.port.start();*


> > log("begin");
> > </script>
>
> > </body>
> > </html>
>
> > pong.js:
>
> > onconnect = function(event) {

> > *       event.ports[0].onmessage = function(e) {


> > event.ports[0].postMessage("pong"); };

> > *       event.ports[0].*postMessage*("connect")
> > };
>
> > -atw

> >> To post to this group, send email to chromium-ht...@chromium.org.


> >> To unsubscribe from this group, send email to

> >> chromium-html5+unsubscr...@chromium.org<chromium-html5%2Bunsubscr...@chromium.org>

Ivan Žužak

unread,
Feb 27, 2010, 12:31:01 PM2/27/10
to Nico Weber, Chromium HTML5
That did it, Nico - thanks!

Everything seems to be working now, including the example from Simon.

Cheers,
Ivan

On Sat, Feb 27, 2010 at 17:59, Nico Weber <tha...@google.com> wrote:
> There was a recent change that disallows local html files to access other
> local files. That might be the cause. Check the googlechromereleasenotes
> blog for a flag that gives you the old behavior.
>
> Nico

>> Following up on this - for #2, I ...


>
>> On Tue, Feb 23, 2010 at 11:12 AM, Drew Wilson <atwil...@chromium.org>
>> wrote:

>> > First off, I'm re...


>
>> >        event.ports[0].postMess*aa*ge("connect")
>
>>
>> > Note the double "a" in postMessaage(). It turns out that parse
>> > exceptions

>> > generated within...


>
>> >http://code.google.com/p/chromium/issues/detail?id=36577to track this
>
>> > issue.
>>
>> > 2) The messageHandler function won't work, because MessageEvent won't
>> > have

>> > even...


>
>> > On Mon, Feb 22, 2010 at 8:34 PM, rektide <rekt...@voodoowarez.com>
>> > wrote:
>>

>> >> I'm trying to u...


>
>> >> To post to this group, send email to chromium-ht...@chromium.org.
>
>> >> To unsubscribe from this group, send email to
>
>> >>
>> >> chromium-html5+unsubscr...@chromium.org<chromium-html5%2Bunsubscr...@chromium.org>
>
>> >> .
>> >> For more options, visit this group at

>> >>http://groups.google.com/a/chromium.org/group/...

Drew Wilson

unread,
Mar 1, 2010, 1:28:32 AM3/1/10
to Ivan Zuzak, Chromium HTML5
Thanks, Ivan - I'll give Simon's test case a shot tomorrow, since it sounds like something bad is happening there (the crash).

-atw

To post to this group, send email to chromiu...@chromium.org.
To unsubscribe from this group, send email to chromium-html...@chromium.org.

Ivan Žužak

unread,
Mar 1, 2010, 2:10:22 AM3/1/10
to Drew Wilson, Chromium HTML5
Drew - Simon's test case is working for me now (after updating
Chromium to the latest version and starting with
--allow-file-access-from-files as Nico suggested). Don't know why it
was crashing in the old version. (Wrote the same on the html5 chromium
mailing list, looks like you got dropped from the CC).

Thanks anyway! Now I'm cheering for supporting logging of worker
exceptions in the console :).
Ivan

Drew Wilson

unread,
Mar 1, 2010, 2:03:12 PM3/1/10
to Ivan Žužak, Chromium HTML5
I've been able to reproduce this crash using the Mac dev channel build (5.0.335.0), sporadically (it often takes several reloads to make it happen). It only seems to happen with the iframe test, which is interesting.

I'll investigate further, but I've logged http://code.google.com/p/chromium/issues/detail?id=37100 in the meantime. Thanks again for the report!

-atw
Reply all
Reply to author
Forward
0 new messages