MessageChannel

Lesson 4 · ~8 minutes · a real Worker this time

The worker already has a pipe

A dedicated worker is already two entangled ports. Mint a pair only when you need a second pipe.

new Worker(url) sets up a MessagePort the page never sees. worker.postMessage and self.postMessage are that port. Its port message queue is enabled at creation, so Worker has no start(), and addEventListener("message") on the worker already dispatches. The hop has no targetOrigin: the second argument is a transfer list, the same way you moved a port into an iframe. (HTML §10.1.3.2)

const worker = new Worker(url);
worker.onmessage = onMsg;
worker.postMessage({ job: "crunch" });   // implicit pipe — enough

const { port1, port2 } = new MessageChannel();
port1.onmessage = onExtra;
worker.postMessage("stream", [port2]);  // second pipe — only if you need one

Mint when the implicit stream is the wrong shape: a second logical conversation, a port you can close() without killing the worker, or a capability you hand to a third context (another worker, an iframe, a library caller). The spec’s crypto-library example is that pattern: keep port1, ship port2 with the command. (HTML §10.1.2.6)

Choose or reject

You already have Use
The same JS world (a React child, a function) Call it. No channel.
A window handle, and origin is the question window.postMessage + targetOrigin
A name, and every same-origin listener should hear BroadcastChannel
A dedicated worker, one stream with its creator The implicit port. Do not mint.
A second stream, or an end to hand off new MessageChannel(), transfer one port

Feel both pipes

A real dedicated worker. Ping the implicit pipe. Then mint a pair, move port2 in the worker’s transfer list, and talk on that extra port. Ping implicit again: it is still its own pipe.

The lab needs JavaScript in this page.

Check

A dedicated worker and its creator need one two-way stream. What do you use?

You listen with worker.addEventListener("message", …) and never call start(). What happens?

When do you mint MessageChannel to talk to a dedicated worker?

You move port2 into a dedicated worker. Does that hop take targetOrigin?

A React parent wants a child in the same tree to report a click. What do you use?

Many same-origin tabs should hear “user logged in”. What do you use?

Primary source

Read HTML Living Standard §10.1.3.2 (implicit port, queue already enabled, transfer as the second argument). Then the extra-pipe pattern in §10.1.2.6 (source.postMessage(message, [messageChannel.port2])).

Ask the teacher

If “why isn’t the worker just a MessageChannel?” is still mushy — ask. Next: lesson 5 — both ends in two iframes, parent off the pipe. Pocket cards: entangled ports, port API, transfer, choose.