PWA(Progressive Web App)入门系列:消息通讯

栏目: 前端 · 发布时间: 4年前

内容简介:serviceWorker 的能力决定它要处理的事情,网站页面的部分逻辑处理会转移到 serviceWorker 层进行处理,这里就要页面层和 serviceWorker 层进行交互来实现消息通讯。下面就说一下两个环境下的消息通讯。这里列举出窗口层到 serviceWorker 层的通讯方法。

serviceWorker 的能力决定它要处理的事情,网站页面的部分逻辑处理会转移到 serviceWorker 层进行处理,这里就要页面层和 serviceWorker 层进行交互来实现消息通讯。

下面就说一下两个环境下的消息通讯。

窗口向 serviceWorker 通讯

这里列举出窗口层到 serviceWorker 层的通讯方法。

1. ServiceWorker.postMessage

页面层可以通过 ServiceWorker 接口的 postMessage 来实现页面到 serviceWorker 环境的通讯。

ServiceWorker 接口的获取:

ServiceWorker 接口获取有两种方式

  • navigator.serviceWorker.controller ,常用这种方式。
  • navigator.serviceWorker.ready.then(swReg => swReg[state]) :state 为 {installing, waiting, active}

当 postMessage 后,serviceWorker 环境采用 onmessage 事件进行处理。

发送消息:

PWA(Progressive Web App)入门系列:消息通讯

发送消息实现:

index.html

// 页面 window 环境

if(navigator.serviceWorker.controller) { // 需要判断是否受控
	navigator.serviceWorker.controller.postMessage('消息');  // postMessage 的第一个参数可以是由结构化克隆算法处理的任何值或JavaScript对象,也包括循环引用。
}
复制代码

sw.js

// serviceWorker 环境

self.addEventListener("message", e => {
  console.log("message", e);
  // 从 e.data 里面取 postMessage 过来的数据
})
复制代码

接收消息:

PWA(Progressive Web App)入门系列:消息通讯

页面层 window 环境下接收消息需要在 ServiceWorkerContainer 接口上监听 onmessage:

navigator.serviceWorker.onmessage
复制代码

serviceWorker 层做定向 Client 的获取有以下方式:

// 1. 通过 e.source.id 来定向发送消息

self.addEventListener("message", e => {
	const client = await self.clients.get(e.source.id);
	client.postMessage('发给页面层的消息');
})

// 2. 直接 e.source 来定向发送消息

self.addEventListener("message", e => {
	e.source.postMessage('发给页面层的消息');
})
复制代码

2. ServiceWorkerRegistration.sync.register

第二种方式,是使用 sync 的方式来实现页面层到 serviceWorker 层的通讯。

PWA(Progressive Web App)入门系列:消息通讯

这种通讯的弊端是单向的,且不可控。

但优势也很明显,对于后台同步十分有用,一旦注册 sync 在 online 的状态下会立即触发 serviceWorker 环境下的 onsync 事件,serviceWorker 可根据具体逻辑处理,直到 e.waitUntil 返回 Promise.resolve() 才会完成 sync,并把 sync 的 tag 清除,否则会一直按照某个周期执行,知道 e.lastChance == true

// 页面层环境

navigator.serviceWorker.ready.then(swReg => {
	swReg.sync.register('同步tag')
})
复制代码
// serviceWorker 层环境

self.addEventListener("sync", e => {
	if(e.tag == '同步tag') {
		e.waitUntil(
	    	new Promise((res, rej) => {
	    		// 逻辑处理 ...
	    		return res();
	    	})
	    )
    }
})
复制代码

3. MessageChannel

MessageChannel 是一个点对点的消息通道,可以很方便的实现消息的双向通讯。

PWA(Progressive Web App)入门系列:消息通讯

构造函数:

构造函数很简单,不需要任何参数

var channel = new MessageChannel();
复制代码

属性:

  • MessageChannel.port1
  • MessageChannel.port2

属性中的两个 port 为 MessagePort 接口实现,具备以下方法:

  • postMessage
  • start
  • close

具备事件监听:MessagePort.onmessage。

这里发消息时,主要以环境下的 postMessage 配合使用。

// 页面层环境

if(navigator.serviceWorker.controller) {
	var c = new MessageChannel();
	c.port1.onmessage = e => {
		// 收到传给 port1 的消息
	}
	
	// 向 port2 发送消息
	navigator.serviceWorker.controller.postMessage('消息', [c.port2])
}
复制代码
// serviceWorker 层

self.addEventListener("message", e => {
	// 从 e.ports 里取 MessagePort
	e.ports[0] && e.ports[0].postMessage('向port1发送消息')
})
复制代码

注意:MessageChannel 创建的通道会受 serviceWorker 的 stopWorker 影响,导致 MessageChannel 通道 close,也就是表现为通道只能用一次。所以使用 MessageChannel 通讯时,每次都要创建新的通道。

serviceWorker 向窗口通讯

上面说的是窗口页面层向 serviceWorker 环境的通讯,同样 serviceWorker 环境层也需要向页面层通讯。

在 serviceWorker 环境下主要有两种向页面层通讯的方式。

1. BroadcastChannel

第一种是 BroadcastChannel,也就是广播信道通讯。

构造函数:

构造函数很简单, channel 参数为一个字符串。

var channel = new BroadcastChannel(channel);
复制代码

属性:

  • BroadcastChannel.name :构造时的信道名。

事件:

  • onmessage
  • onmessageerror

方法:

  • postMessage()
  • close()
PWA(Progressive Web App)入门系列:消息通讯
// 页面层

var bc1 = new BroadcastChannel('c1');

bc1.onmessage = e => {
	// 页面层收到广播,逻辑处理
}
复制代码
// serviceWorker 层

var bc1 = new BroadcastChannel('c1');

bc1.postMessage('发送广播消息');
复制代码

2. client.postMessage

第二种就是获取相应的 client 进行 postMessage。

如果从 onmessage 中,是可以获取到相应的 sorce client 的,从而进行双向通讯。但在自发情况下,只能对所有 client 进行广播通讯。

PWA(Progressive Web App)入门系列:消息通讯
// serviceWorker 环境

clients.matchAll({
  type: "window"
})
.then(windows => {
  for (const win of windows) {
    win.postMessage('发送消息到页面');
  }
});
复制代码

博客名称:王乐平博客

CSDN博客地址: blog.csdn.net/lecepin

PWA(Progressive Web App)入门系列:消息通讯
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Designing Data-Intensive Applications

Designing Data-Intensive Applications

Martin Kleppmann / O'Reilly Media / 2017-4-2 / USD 44.99

Data is at the center of many challenges in system design today. Difficult issues need to be figured out, such as scalability, consistency, reliability, efficiency, and maintainability. In addition, w......一起来看看 《Designing Data-Intensive Applications》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具