3

Broadcast Channel API似乎是postMessageChannel Messaging API(又名MessageChannel )的替代品。我在最近版本的 Google Chrome 中成功地使用了这两者来发送共享数组缓冲区;但是,我无法使用广播通道 API 发送共享数组缓冲区。

Mozilla 在https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel的文档引用了https://html.spec.whatwg.org/multipage/web-messaging.html#broadcastchannel的规范,其中说:

对于目的地中的每个目的地...

  1. 让数据为 StructuredDeserialize(serialized, targetRealm)。如果这引发异常,则捕获它,使用 MessageEvent 在目的地触发名为 messageerror 的事件,并将 origin 属性初始化为 sourceOrigin 的序列化,然后中止这些步骤。

StructuredDeserialize 在https://html.spec.whatwg.org/multipage/structured-data.html#structureddeserialize中定义,似乎暗示它涵盖了 SharedArrayBuffers:

  1. 否则,如果serialized.[[Type]]是“SharedArrayBuffer”,那么:如果targetRealm对应的agent集群没有serialized.[[AgentCluster]],那么抛出“DataCloneError”DOMException。否则,将 value 设置为 targetRealm 中的新 SharedArrayBuffer 对象,其 [[ArrayBufferData]] 内部槽值已序列化。[[ArrayBufferData]] 并且其 [[ArrayBufferByteLength]] 内部槽值已序列化。[[ArrayBufferByteLength]]。

阅读本文,在我看来这应该可行,但我收到一个消息事件,其中数据只是null. 如果这是一个安全问题,我希望得到一个 messageerror 事件而不是 message 事件。

这是我的最小测试用例:

broadcast-test.html(必须从 http 服务器提供 - 不能通过 file:// 工作)

<!DOCTYPE html>
<html>
  <head><title></title></head>
  <body>
    <script src="broadcast-test.js"></script>
  </body>
</html>

广播-test.js

const isThisTheWorker = this.document === undefined
const broadcastChannel = new BroadcastChannel('foo')

if (!isThisTheWorker) {
  broadcastChannel.addEventListener('message', (event) => {
    console.log('main received', event.data)
    const sab = new SharedArrayBuffer(100)
    broadcastChannel.postMessage({ hello: 'from main', sab })
  })
  var myWorker = new Worker('broadcast-test.js')
}
else {
  broadcastChannel.addEventListener('message', (event) => {
    console.log('worker received', event.data)
  })
  broadcastChannel.postMessage({ hello: 'from worker' })
}

观察到的控制台输出:(Windows 10 上的 Chrome 84.0.4147.135)

主要收到{你好:“来自工人”}

工人收到空

谷歌浏览器的实现是不正确的,还是我误解了规范?

4

0 回答 0