日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/7/14 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PWA(Progressive Web App)入门系列:消息通讯 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

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 事件進行處理。

發送消息:

發送消息實現:

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 過來的數據 }) 復制代碼

接收消息:

頁面層 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 層的通訊。

這種通訊的弊端是單向的,且不可控。

但優勢也很明顯,對于后臺同步十分有用,一旦注冊 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 是一個點對點的消息通道,可以很方便的實現消息的雙向通訊。

構造函數:

構造函數很簡單,不需要任何參數

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 里取 MessagePorte.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()
// 頁面層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 進行廣播通訊。

// serviceWorker 環境clients.matchAll({type: "window" }) .then(windows => {for (const win of windows) {win.postMessage('發送消息到頁面');} }); 復制代碼

博客名稱:王樂平博客

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

本作品采用知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。

轉載于:https://juejin.im/post/5d067f22e51d457778117390

總結

以上是生活随笔為你收集整理的PWA(Progressive Web App)入门系列:消息通讯的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。