[36] MessagePort
インターフェイスはコンストラクターを持ちません。
[37] 作成するには、 MessageChannel
オブジェクトなどを作成する必要があります。
[39] 環境設定群オブジェクト所有者に関する新しいMessagePort
オブジェクトの作成は、
次のようにしなければなりません。
[40] この処理は、次の場面から呼び出されます。
[33] MessagePort
インターフェイスは、
文書環境とワーカー環境と AudioWorklet
に晒されています >>32。
[96] MessageChannel
オブジェクトを作成すると、
port1
と port2
の2つの IDL属性から
MessagePort
にアクセスできます。
[98] postMessage
メソッドで送信する MessagePort
を指定できます。
[97] postMessage
の受信やワーカーの作成で
MessageEvent
イベントが発火された時は、
ports
IDL属性で MessagePort
の配列にアクセスできます。
[100] ワーカーは、暗示的ポートとして MessagePort
を持ちます。
[101] SharedWorker
オブジェクトは、
port
IDL属性で MessagePort
を持ちます。
[99] WorkerGlobalScope
は、
ワーカーのポート群として
MessagePort
のリストを保持しています >>149。
[170] protected worker かどうかの判定で参照されます。
[171] ワーカーを走らせる処理の最後の片付けの段階で disentangle の実行のため参照されます。
[38] EventTarget
としての状態に加えて、
次の状態を持ちます。MessagePort
オブジェクト。
>>107 も参照。
[34] EventTarget
を継承しています >>32。
[135] MessagePort
オブジェクトは、
ポートメッセージキューを持ちます。
初期状態は空です。 >>65
[136] MessagePort
オブジェクトのポートメッセージキューは、
無効または有効のいずれかの状態にあります。
初期状態は無効です。一旦これを有効にすると、無効には戻せません。
>>65
[137] MessagePort
オブジェクトは、
既に出荷済みフラグを持ちます。
初期状態は偽です。
>>32
[64] 2つの状態が、 postMessage
の結果生じる
message
イベントの実行タイミングに影響します。
仕様書の規定は複雑でわかりにくいですが:
[143] ポートメッセージキューと未出荷済みポートメッセージキューは、 タスクのキューであるにも関わらず、タスク源である >>32 と規定されています。それでいて、イベントループによって (実行されるべきタスクのリストとして) 使われる >>32 ともされていて、 イベントループの持つタスクキューの一種であるかのようにも捉えられます。
[144] 仕様書の履歴を辿ってみると、元はポートメッセージキューはその名の通り
message
イベントのキューでした。
このキューに追加されたイベントは、(準備が整い次第)
イベントを発火するタスクがイベントループのタスクキューに追加され、
ポートメッセージキューからは削除されることになっていました。
[145] これがその後の改訂 >>133 で、ポートメッセージキュー自体がタスクのキューになりました。
コミットメッセージで MessagePort
が他のイベントループに渡った時にイベントが失われないための変更だと説明されており、
MessagePort
の Transfer でイベントを新イベントループ下に移動させることが狙いだったようです。
[146] この変更で、ポートメッセージキューはタスク源であるということになりました。 仕様書は「タスクはタスク源から来る」としか言っておらず、 タスク源とは何なのか (ラベルなのかリストなのか) はよくわかりませんが、 (実装でどう扱うかは別として、仕様書の裏の考え方としては) タスク源とはそれ自体がタスクのリスト (タスクキュー部分リスト) で、 そのようなリストをいくつか束ねたものがタスクキューだ、 といえるのかもしれません。
[63] クライアントメッセージキューと似ています。
[43] 2つの MessagePort
を関連付けた状態とすることを
entangle といいます。
ポート1とポート2の entangle は、次のようにしなければなりません。
[50] この処理が済んだ状態を、ポート1とポート2が entangle されているといいます >>32。
[102] entangle 状態を解除することを、 disentangle >>32 といいます。
MessagePort
ポートの disentangle は、
次のようにしなければなりません。
[105] disentangle は、次の場面で呼び出されます。
[106] entangle の中から disentangle が呼び出される、つまり entangle
関係が書き換えられて他の MessagePort
と関連付けられた状態になるのは、
Transfer からの呼び出しの場合のみです。すなわち postMessage
により MessagePort
が送られて、他方の
MessagePort
の接続先が新しい方に差し替えられる場合です。
これ以外で disentangle された MessagePort
は、二度と
entangle
されることはありません。
[52] MessagePort
オブジェクトは、 transferable object
です。 >>32
[53] MessagePort
オブジェクトの
transfer steps は、値とデータ保持子について、
次のようにしなければなりません >>32。
null
以外なら、null
に設定します。[169] transfer-receiving steps は、データ保持子と値について、 次のようにします >>32。
null
以外なら、[67] MessagePort
ポートのポートメッセージキューの有効化は、
次のようにしなければなりません >>32。
[68] これによって、それまでイベントループのタスクキューの処理で無視されていた本ポートメッセージキューのタスクが、処理対象にと変化します。
[91] 次の場面で呼び出されます。
[85] MessagePort
ポートの出荷は、
次のようにしなければなりません >>32。
[87] HTML Standard では、これは Transfer (>>53) から実行される処理となっています。
意味的には、それ以外にワーカーを走らせる処理、 new Worker
、
new SharedWorker
からも実行されるべきではないかとも思われますが、
そうは規定されていません。歴史的経緯による誤りなのか、意図通りなのかははっきりしません。
現実問題どれだけその差が観測できるかは微妙なところかもしれません。
[71] 処理を MessagePort
ポートのポートメッセージキューに追加するには、
次のようにしなければなりません。
[129] これは postMessage
から呼び出されます。
[107]
MessagePort
ポートが entangle されているなら、
次のいずれかとしなければなりません >>108。
[120] 実装上、 entangle されているポート同士が異なるプロセスで動作しているなど、 直接強い参照を保持しているとすると実現困難な場合があるため、 2つの方法が認められているものと思われます。2つの方法は完全に等価なわけではありませんが、 著者のスクリプトから直接観測可能な挙動としては同一です。
[139] ワーカーに関しては、 WorkerGlobalScope
のワーカーのポート群として当該ワーカー外に entangle されたすべての
MessagePort
のリストを大域オブジェクトが保持することになっています。
これは事実上 >>119 を求めるものです (他の等価な実装方法も理論上はあり得ますが...)。
文書環境に関しても、同様に MessagePort
のリストを保持するのが現実的でしょう。
[157] 実装上は、 disentangle されないまま両端ともスクリプトから参照されなくなった時に、 ポート群から除去されてこれらがごみ収集されるよう、注意が必要です。
[148] 同じ環境内のポート同士は、 >>118 の方法を採っても、 >>119 の方法に準ずることにしても良さそうです。
[121] MessagePort
がごみ収集されないということは、
そこに登録されたイベントリスナーがごみ収集されないということです。
つまりこの要件は、イベントリスナーを登録した後に MessagePort
への参照が破棄されたとしても、相手方のポートが生きている限りはイベントリスナーが呼び出される可能性を維持するためのものです。
[109] 未実行のタスクと MessagePort
のごみ収集の関係として、
次のように規定されています。
[115] このうち >>113 は通常のタスクであれば当然にタスクからイベント対象への強い参照が維持されているはずと考えられるところ、
message
については実行時点で含まれるポートメッセージキューの
MessagePort
をイベント対象とする (>>71)
との変則的な規定があるための条件なのでしょうか。
[116] >>114 は、逆に言えばポートメッセージキューが無効の場合は実行されずに捨てられる (かもしれない) し、空になったら捨てられる (かもしれない) ということです。
[117] >>113 は >>114 に含まれるようにも読めますが、イベントループがタスクを実行しようとしてポートメッセージキューから取り出した瞬間に空になって
MessagePort
が破棄されないために >>113 が必要なのでしょうか。
と思いましたがタスクは実行が終わるまでタスクキューに残ったままですよね...
[131] >>113 はタスクキューにタスクが入っていれば、という規定になっていて、
ポートメッセージキューとは言っていません。ポートメッセージキューはタスク源であるとはされていますが、
タスクキューとはされていません (いかにもタスクキューっぽい名前ですが)。
従ってポートメッセージキューが無効なら、 >>113 の条件には合致しないものと思われます。
(無効のまま MessagePort
が破棄されたなら、有効化する手段がなくなるので、
捨てても捨てなくても観測できません。)
[156] 現実には MessagePort
が無効のまま破棄された時、
タスクキュー内にポートメッセージキューのタスク
(がイベント対象として保持している MessagePort
自身への参照)
もごみ収集されるよう、注意する必要があります。
MessageChannel
インターフェイス port1
属性、 port2
属性[27] MessageChannel
インターフェイスの
port1
IDL属性と
port2
IDL属性 >>26
は、それぞれ文脈オブジェクトのポート1とポート2を返します。
[28] MessageChannel
オブジェクトのポート1とポート2は、
コンストラクターによって新たに作成された MessagePort
オブジェクトがそれぞれに設定されます。これらの値は変化することはありません。
[29] 2つのポートは、作成された時点では (異なるオブジェクトであることを除けば) まったく同じ初期状態です。どちらをどう使うかは、著者が決めることができます。
MessagePort
インターフェイス start
メソッド[88] MessagePort
インターフェイスの
start
メソッドは、次のようにしなければなりません >>32。
MessagePort
インターフェイス close
メソッド[93] MessagePort
インターフェイスの
close
メソッドは、次のようにしなければなりません >>32。
[112] MessagePort
が不要になったら、明示的に閉じて disentangle
することが強く勧められています。
明示的に閉じずないと必ずしも即座にごみ収集されるとは限らないため (>>107)、
メモリーを無駄にすることとなります。 >>108
MessageEvent
インターフェイス ports
属性[162] MessageEvent
インターフェイスと
MessageEventInit
辞書の
ports
IDL属性/辞書メンバー >>161 は、
受信した MessagePort
の配列を表します。
[163] 値は MessagePort
の sequence
です
>>12。辞書での既定値は空の配列です >>12。
[73] ポートメッセージキューはここで導入されました。
open と closed の2つの状態を持っていました。
この時同時に追加された start
メソッドを呼び出すか、
onmessage
IDL属性に値を設定するかのいずれかにより、
closed から open へと遷移することとされていました。
[134] これまで投稿済みメッセージタスク源が使われていましたが、 >>133 により、使われなくなりました。
[1] IRC logs: freenode / #whatwg / 20130604 ( ( 版)) http://krijnhoetmer.nl/irc-logs/whatwg/20130604
[2] [whatwg] onclose events for MessagePort ( ( 版)) http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2013-October/041298.html
[3] Web Applications 1.0 r8306 People apparently don't like it when the spec requires things that are impossible to implement, go figure. (In this case, synchronously detecting that one of the MessagePorts being Transferred in the MessagePort message is actually the target of the message. You can't necessarily know this synchronously, since if the port has been shunted around between workers, you might only discover who the final target actually is after the message has itself bounced between threads for a while.) ( ( 版)) http://html5.org/tools/web-apps-tracker?from=8305&to=8306
[4] [whatwg] onclose events for MessagePort ( ( 版)) http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2013-December/041739.html
[5] Web Applications 1.0 r8336 Add a way to catch the other side of a port having a catastrophic death. ( ( 版)) http://html5.org/tools/web-apps-tracker?from=8335&to=8336
[6] Web Applications 1.0 r8341 Updates for r8297, fixing <option> to treat 'dirtiness' correctly, and r8336, fixing 'error' events sent to MessagePort objects to not race messages sent from those ports (or, worse, the event that the port is delivered on...). ( ( 版)) http://html5.org/tools/web-apps-tracker?from=8340&to=8341
[7] IRC logs: freenode / #whatwg / 20131218 ( ( 版)) http://krijnhoetmer.nl/irc-logs/whatwg/20131218
[8] Web Applications 1.0 r8342 Make sure subsequent owners of an ill-fated port's friend can know about that fate ( ( 版)) http://html5.org/tools/web-apps-tracker?from=8341&to=8342
[9] [whatwg] onclose events for MessagePort ( ( 版)) http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2014-January/041953.html
[10] Web Applications 1.0 r2020 Make MessagePort objects not be owned by Windows necessarily, and remove ownerWindow. ( ( 版)) https://html5.org/r/2020
[11] Web Applications 1.0 r2116 Change 'unload' to 'close' for MessagePorts. ( ( 版)) https://html5.org/r/2116
[12] Web Applications 1.0 r2531 Simplify the way messages in ports are handled when the destination's document is not available. ( ( 版)) https://html5.org/r/2531
[13] Web Applications 1.0 r2032 Remove redundant event listeners on MessagePort. ( ( 版)) https://html5.org/r/2032
[14] Web Applications 1.0 r2031 MessagePort should implement EventTarget. ( ( 版)) https://html5.org/r/2031
[15] Web Applications 1.0 r3346 Allow cloning and posting of closed ports. (credit: dw) ( ( 版)) https://html5.org/r/3346
[16] Web Applications 1.0 r2885 postMessage() methods that take MessagePort objects now take MessagePortArray objects. ( ( 版)) https://html5.org/r/2885
[17] Web Applications 1.0 r2024 Simplify garbage collection for ports even further. Define dicarding of Document objects better for ports. Prevent inactive documents from receiving messages. ( ( 版)) https://html5.org/r/2024
[18] Web Applications 1.0 r3227 Fix the garbage collection rules for ports to actually make sense, and add a note for authors urging them not to rely on the gc for ports. ( ( 版)) https://html5.org/r/3227
[19] Web Applications 1.0 r3147 Clarify MessagePort GC rules. ( ( 版)) https://html5.org/r/3147
[20] Web Applications 1.0 r2358 MessagePorts shouldn't be GCed even when their queue is closed if they have events targetted at them. (credit: ap) ( ( 版)) https://html5.org/r/2358
[21] Web Applications 1.0 r2023 Simplify message ports: use queueing instead of transient 'active' functionality. Also, make localStorage use the same mechanism for obtaining origin as openDatabase(). ( ( 版)) https://html5.org/r/2023
[22] Web Applications 1.0 r2357 Define MessagePort such that they won't be garbage collected while a message is outstanding. (credit: ap) ( ( 版)) https://html5.org/r/2357
[23] Add <script type="module"> and module resolution/fetching/evaluation · whatwg/html@cd1a9fb ( 版) https://github.com/whatwg/html/commit/cd1a9fb1e83f7d0bc30be8b34ecdaf444a0b19a4
[24] Write structured clone algorithm in terms of ECMAScript · whatwg/html@bfb960c ( 版) https://github.com/whatwg/html/commit/bfb960c938580c95e77365e614218b952f96375b
[25] Use FrozenArray for Navigator#languages and MessageEvent#ports · whatwg/html@e4df68a ( 版) https://github.com/whatwg/html/commit/e4df68a41b86753c7fcdd0d8ea4615f63ffc87e9
[158] 28813 – There's no way to tell when a MessagePort is closed. () https://www.w3.org/Bugs/Public/show_bug.cgi?id=28813
[159] Use FrozenArray for Navigator#languages and MessageEvent#ports · whatwg/html@e4df68a ( 版) https://github.com/whatwg/html/commit/e4df68a41b86753c7fcdd0d8ea4615f63ffc87e9
[160] Make MessageEvent's ports attribute non-nullable (cdumez著, ) https://github.com/whatwg/html/commit/df2c0c448612d5b8ab85ad3c6ce0255ee11c0b01
[164] Breaking: refactor structured clone into serialize/deserialize (domenic著, ) https://github.com/whatwg/html/commit/97d644c97335956610a31e8ad98d1a388c063e84
[62] Breaking: refactor structured clone into serialize/deserialize (domenic著, ) https://github.com/whatwg/html/commit/97d644c97335956610a31e8ad98d1a388c063e84
[141] Editorial: restructure ownership of workers to parent-owners (annevk著, ) https://github.com/whatwg/html/commit/59a4750f475acd789ee436b4906972ba2081d8b3
[172] Editorial: restructure ownership of workers to parent-owners (annevk著, ) https://github.com/whatwg/html/commit/59a4750f475acd789ee436b4906972ba2081d8b3
[173] Meta: remove "ILLFATED" MessagePort design (annevk著, ) https://github.com/whatwg/html/commit/1208d255eddebe7efc3bba59bc297709e3b30660
[174] Introduce MessagePort on AudioWorkletNode/Processor by hoch · Pull Request #1233 · WebAudio/web-audio-api () https://github.com/WebAudio/web-audio-api/pull/1233
[175] Expose MessagePort to AudioWorklet (hoch著, ) https://github.com/whatwg/html/commit/458347c0d677dbd6e2414d6f435c77fbb9c9eab1
[176] Expose MessagePort to AudioWorklet · Issue #3081 · whatwg/html () https://github.com/whatwg/html/issues/3081
[177] Fix 3081: Expose MessagePort in AudioWorklet by hoch · Pull Request #3082 · whatwg/html () https://github.com/whatwg/html/pull/3082
[178] Make MessageChannel's close() set [[Detached]] (annevk著, ) https://github.com/whatwg/html/commit/ee5ff06ce0f13ecd73ab4461983f6faec7e88a7a
[180] Make MessagePort's close() set [[Detached]] by annevk · Pull Request #3584 · whatwg/html () https://github.com/whatwg/html/pull/3584
[181] Make MessagePort's close() detach by annevk · Pull Request #10123 · w3c/web-platform-tests () https://github.com/w3c/web-platform-tests/pull/10123
[182]
Mobile Safari の
MessagePort
、
<input type=file>
で iOS の画像選択に一旦遷移して戻ってくると、
何を送っても相手に届かない状態になる??