HTML5 API 多端通信桥 MessageChannel 技术

这个特别有意思,可以将其理解为通信桥的概念,桥有两个端(port1,port2)只要将port1,port2指定到任意两个进程,无论是iframe-iframe,iframe-worker,parent-child-iframe,worker-worker等,只要搭好,两者就可以实时通信了。这解决了让parent作为中转站这种头大的问题,以下是该技术调研的细节。

相关链接:MessageChannel - Web API 接口参考 | MDN

在MessageChannel出现之前,跨上下文(例如,主线程、Web Workers、Service Workers或者不同的窗口或iframe)通信主要依赖于postMessage和onmessage事件。这种方式虽然有效,但在某些情况下可能会比较麻烦。

例如,假设你有一个主线程和两个Web Workers,你希望这两个Web Workers能够直接通信。在MessageChannel出现之前,你可能需要这样做:

  1. Worker A向主线程发送一个消息。

  2. 主线程接收到这个消息后,再将它转发给Worker B。

  3. Worker B接收到这个消息后,再向主线程发送一个回复。

  4. 主线程接收到这个回复后,再将它转发给Worker A。

这种方式需要主线程作为中介,进行大量的消息转发,这可能会增加主线程的负担,降低应用程序的性能。

而有了MessageChannel之后,你可以直接在两个Web Workers之间创建一个通信通道,然后这两个Web Workers就可以直接通信,无需通过主线程。这样可以减少主线程的负担,提高应用程序的性能。

此外,MessageChannel还支持传输Transferable对象,这可以避免数据的复制,进一步提高性能。而在MessageChannel出现之前,如果你想在不同的上下文之间传输大量的数据,你可能需要进行昂贵的数据复制或者序列化和反序列化操作。

总的来说,MessageChannel提供了一种更简单、更直接、更高效的跨上下文通信方式。

HTML5 中案例代码

https://github.com/mdn/dom-examples/tree/main/channel-messaging-basic

下面是我根据 ChatGPT 探索的两个 iframe 的双向通信代码,记住 iframe 和 webview 一样,在没将页面 load 完成时,你发过去的消息,嵌入页面收不到,这个在测试时是不报错的,很恶心!

index.html



  
    
    
    
    Channel messaging demo
  
  
    

Channel messaging demo

My body

Page1.html




    
    
    
    My page title
    


iFrame body

Page2.html




    
    
    
    My page title


iFrame body

三者之间的实现效果

HTML5 API 多端通信桥 MessageChannel 技术_第1张图片

补充知识

postMessage 的三个参数分别有什么作用?

window.postMessage(message, targetOrigin, [transfer])

targetOrigin参数是一个字符串,表示消息的目标源(协议+主机+端口)。你可以使用这个参数来限制哪些窗口可以接收你的消息,以提高安全性。

以下是使用targetOrigin参数的示例:

htmlCopy code


当 targetOrigin="*"时,则代表着向所有 iframe 进行广播的效果

window.onmessage 和 window.addEventListener('message', ...)两者之间的区别是什么?

window.onmessage和window.addEventListener('message', ...)都是用于监听message事件的方法,但它们的使用方式和行为有一些不同。

window.onmessage:这是一个事件处理属性,你可以将它设置为一个处理函数,这个函数会在message事件发生时被调用。如果你多次设置window.onmessage,那么后面的设置会覆盖前面的设置。也就是说,你只能有一个onmessage处理函数。

javascriptCopy codewindow.onmessage = (event) => {
  console.log(event.data);
};

window.addEventListener('message', ...):这是一个方法,你可以用它来添加一个或多个message事件的监听器。如果你多次调用addEventListener,那么每次调用都会添加一个新的监听器,而不会覆盖旧的监听器。也就是说,你可以有多个message事件的监听器。

javascriptCopy codewindow.addEventListener('message', (event) => {
  console.log(event.data);
});

总的来说,如果你只需要一个message事件的处理函数,你可以使用window.onmessage。如果你需要多个message事件的处理函数,或者你需要更复杂的事件处理(例如,使用捕获阶段,或者移除事件监听器),你可以使用window.addEventListener('message', ...)

 

你可能感兴趣的:(Javascript,html5,前端,html)