原文請查閱
這裏,略有刪減,本文採納
學問同享署名 4.0 國際許可協定同享,BY
Troland。
本系列延續更新中,Github 地點請查閱這裏。
這是 JavaScript 事情道理的第九章。
如今讓我們把注重力轉移到網頁推送關照:我們將會檢察其組織,探究發送/吸收關照背地的歷程以及末了分享一下我們在 SessionStack 是怎樣設計運用這些功用來建立新的產物功用的。
推送關照這一功用在挪動端已異常廣泛。不知為什麼,網頁端的推送關照是千呼萬喚始出來,縱然大多數開發者猛烈地要求完成這一功用。
概述
網頁推送關照許可用戶挑選定時從收集運用獵取實時信息。它旨在為用戶從新獵取其感興趣,主要和實時的信息。
推送效勞是基於效勞事情線程的,效勞事情線程在之前的文章中有細緻論述過。
這個狀況下,之所以採納效勞事情線程是因為它會在背景運轉,從而不會壅塞界面的襯着。關於推送關照來講,這是相稱主要的,因為這意味着只要當用戶和推送關照自身舉行交互操縱才會實行推送關照的相干代碼。
音訊推送和關照
音訊推送和關照是兩個差別的接口。
音訊推送
完成音訊推送也許有以下三個步驟:
- 界面-增添客戶端邏輯來讓用戶定閱推送效勞。在收集運用界面中謄寫 JavaScript 代碼邏輯來讓用戶註冊音訊推送效勞。
- 發送音訊-在效勞器端完成接口挪用來觸發向用戶裝備推送音訊。
- 吸收音訊-一旦在瀏覽器端吸收到推送音訊則處置懲罰之。
如今,讓我們細緻論述全部歷程。
兼容性檢測
起首,須要檢測當前瀏覽器是不是支撐音訊推送效勞。可以採納以下兩種簡樸的搜檢:
- 檢測
navigator
對象上的serviceWorker
屬性 - 檢測
window
對象上的PushManager
屬性
都檢測代碼以下:
if (!('serviceWorker' in navigator)) {
// 當前瀏覽器不支撐效勞器事情線程,禁用或許隱蔽界面
return;
}
if (!('PushManager' in window)) {
// 當前瀏覽器不支撐推送效勞,禁用或許隱蔽界面
return;
}
註冊效勞事情線程
如今,音訊推送功用是支撐的。下一下即註冊效勞事情線程。
從之前的文章中你應當很熟悉怎樣註冊效勞事情線程。
要求受權
當註冊效勞事情線程以後,接下來舉行用戶定閱的相干操縱。這須要取得用戶的受權來向其推送音訊。
取得受權的接口相稱的簡樸但有一個瑕玷即接口 接收的參數之前是一個回調函數如今是一個 Promise。因為沒法曉得當前瀏覽器支撐的接口版本,所以須要舉行兼容處置懲罰。
相似如許:
function requestPermission() {
return new Promise(function(resolve, reject) {
const permissionResult = Notification.requestPermission(function(result) {
// 運用回調來處置懲罰燒毀的接口版本
resolve(result);
});
if (permissionResult) {
permissionResult.then(resolve, reject);
}
})
.then(function(permissionResult) {
if (permissionResult !== 'granted') {
throw new Error('Permission not granted.');
}
});
}
挪用 Notification.requestPermission()
會向用戶彈出以下的提示框:
當取得,封閉以及制止權限的時刻,就可以獲得 granted
,default
或許 denied
的效果字符串。
須要注重的是當用戶點擊 制止
按鈕,收集運用將不會再次訊問用戶受權直到用戶手動開啟變動受權狀況。該選項隱蔽於設置面板中。
點擊地點欄最左側的信息按鈕即可彈出受權的彈窗。
經由過程 PushManager 定閱用戶
一旦效勞事情線程註冊勝利且取得受權,就可以在註冊效勞器線程的時刻經由過程挪用 registration.pushManager.subscribe()
來定閱用戶。
全部代碼片段以下(包括註冊效勞事情線程):
function subscribeUserToPush() {
return navigator.serviceWorker.register('service-worker.js')
.then(function(registration) {
var subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: btoa(
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
)
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function(pushSubscription) {
console.log('PushSubscription: ', JSON.stringify(pushSubscription));
return pushSubscription;
});
}
registration.pushManager.subscribe(options)
中有一個 options 對象參數,个中包括有必需或許可選的參數:
- userVisibleOnly:返回的推送定閱是不是僅對定閱用戶可見。必需設置為
true
不然會失足(這是汗青緣由形成的)。 - applicationServerKey:一個包括公鑰的 Base64 編碼的
DOMString
字符串或許ArrayBuffer
,音訊推送效勞器用來考證運用效勞器。
音訊推送效勞器須要天生一對運用效勞器密鑰對-即 VAPID 密鑰對,這關於音訊推送效勞器來講是唯一的。它們是由一對公鑰和私鑰所構成的。私鑰隱秘存儲於推送效勞器端,公鑰用來和客戶端舉行交流通信用的。這些密鑰讓推送效勞分辨定閱用戶的運用效勞器以及確保觸發推送音訊到指定用戶的是同一個運用效勞器。
你只須要一次性天生運用程序私有/公有密鑰對。可以接見 https://web-push-codelab.glit… 天生密鑰對。
當定閱用戶的時刻,瀏覽器向推送效勞傳入 applicationServerKey
(公鑰),意即推送效勞把運用效勞器公鑰和用戶的 PushSubscription
綁定在一同。
歷程以下:
- 收集運用加載完成然後,挪用
subscribe
,傳入效勞器公鑰。 - 瀏覽器向音訊推送效勞提議要求天生一個端點信息並連同密鑰信息一同返回給瀏覽器。
- 瀏覽器把端信息增添到由
subscribe()
promise 所返回的PushSubscription
對象中。
以後,每當須要推送信息的時刻,必需發送一個認證頭个中包括運用效勞器私鑰署名的信息。
每當推送效勞吸收到推送音訊的要求,它會經由過程在傳輸頭中查找已和指定端(第二步中)綁定的公鑰來舉行考證。
PushSubscription 對象
PushSubscription
包括了向用戶裝備推送信息所必備的統統信息。也許包括以下信息:
{
"endpoint": "https://domain.pushservice.com/some-id",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr3PJdAgXS3HGMlLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WArAPIxr4gK0_dQds4yiI=",
"auth":"FPssMOQPmLmXWmdSTdbKVw=="
}
}
endpoint
等於推送效勞地點。當須要推送音訊時,向該地點提議 POST 要求。
keys
對象包括用來加密隨推送音訊一同發送的信息數據的值。
當用戶定閱以後且返回了 PushSubscription
對象,你須要把它保留在推送效勞器上。如許就可以把該定閱相干數據保留在數據庫當中然後從今以後,就可以依據數據庫中的存儲值來給指定的用戶發送音訊。
音訊推送
當須要發送音訊到用戶的時刻,起首須要有一個音訊推送效勞。你關照推送效勞(經由過程接口挪用)須要推送的數據,音訊推送的目的用戶以及恣意前提下怎樣發送音訊。平常狀況下,這些接口挪用是由音訊推送效勞器來完成的。
音訊推送效勞
音訊推送效勞是用來吸收音訊推送要求,考證要求以及推送音訊到指定的用戶瀏覽器端。
請注重這裏的音訊推送效勞並非由你來掌握的-它是第三方效勞。效勞器只是經由過程接口來和音訊推送效勞舉行通信。Google’s FCM 是音訊推送效勞之一。
音訊推送效勞會處置懲罰中心的事宜。比方,當瀏覽器離線,推送效勞在發送各自的音訊之前會列隊音訊且守候直到瀏覽器連網。
開發人員可以挑選讓瀏覽器運用恣意的音訊推送效勞。
但是,一切的音訊推送效勞都具有一樣的接口,如許就不會因為接口不一而增添音訊推送完成的難度。
可以從 PushSubscription
對象的 endpoint
屬性值取得處置懲罰音訊推送的要求 URL 地點。
音訊推送接口
音訊推送效勞接口供應了向用戶發送音訊的一種要領。該接口是一個被稱為 Web Push Protocol 的 IETF 規範協定,內里定義了怎樣挪用音訊推送效勞。
推送的音訊必需得加密。如許可以防備音訊推送效勞窺視到發送的數據。這是至關主要的因為客戶端可以決議運用哪一個音訊推送效勞(可能會運用一些不被信託和不安全的音訊推送效勞)。
音訊推送參數:
- TTL-定義音訊在被刪除且不可以傳輸之前在行列中的保留時長。
- Priority-定義了每條音訊的優先級,如許就可以讓音訊推送效勞只推送高優先級的音訊以輕易用戶節約裝備的電力。
- Topic-為推送音訊設置主題稱號如許就可以運用雷同的主題稱號來置換掉掛起的音訊,所以一旦裝備激活,用戶就不會收到逾期的音訊。
瀏覽器音訊推送事宜
每當發送音訊到如上的推送效勞,音訊會處於待發送狀況直到發作以下幾種狀況:
- 裝備連網。
- 行列中的音訊停止時長凌駕設置的 TTL。
當音訊推送效勞傳輸音訊到瀏覽器,瀏覽器會吸收到,解密,然後分派給效勞事情線程 push
事宜。
划重點這裏縱然沒有打開網頁,瀏覽器依然可以實行效勞事情線程。會發作以下事宜:
- 瀏覽器解密吸收的推送音訊。
- 瀏覽器叫醒效勞事情線程。
- 效勞事情線程吸收到
push
事宜。
監聽推送事宜和在 JavaScript 中寫的別的事宜監聽異常相似。
self.addEventListener('push', function(event) {
if (event.data) {
console.log('This push event has data: ', event.data.text());
} else {
console.log('This push event has no data.');
}
});
須要明白效勞事情線程的一點即其運轉時候是不可工資掌握的。只要瀏覽器可以叫醒和完畢它。
在效勞事情線程中,event.waitUntil(promise)
通知瀏覽器效勞事情線程正在處置懲罰音訊直到 promise 剖析完成,假如想要完成音訊的處置懲罰,那末瀏覽器就不應當中斷效勞事情線程。
以下為處置懲罰 push
事宜的示例:
self.addEventListener('push', function(event) {
var promise = self.registration.showNotification('Push notification!');
event.waitUntil(promise);
});
挪用 self.registration.showNotification()
向用戶彈出一個關照而且返回一個 promise,一旦關照顯現完成即剖析完成。
可以採納可視化的要領來設置相符本身需求的 showNotification(title, options)
要領。title
參數是字符串而 options 是一個相似以下的對象:
{
"//": "視覺選項",
"body": "<String>",
"icon": "<URL String>",
"image": "<URL String>",
"badge": "<URL String>",
"vibrate": "<Array of Integers>",
"sound": "<URL String>",
"dir": "<String of 'auto' | 'ltr' | 'rtl'>",
"//": "行動選項",
"tag": "<String>",
"data": "<Anything>",
"requireInteraction": "<boolean>",
"renotify": "<Boolean>",
"silent": "<Boolean>",
"//": "視覺和行動選項",
"actions": "<Array of Strings>",
"//": "信息選項。沒有視覺效果",
"timestamp": "<Long>"
}
可以在這裏檢察到每一個選項的越發細緻的內容。
每當想要和用戶分享緊要,主要及緊急的信息的時刻,音訊推送效勞是用來關照用戶的一個絕佳的體式格局。
參考資本
- https://developers.google.com…
- https://developers.google.com…
- https://developers.google.com…
- https://developers.google.com…
以下皆為本身擴大的內容。
關照處置懲罰
效勞事情線程可以採納相似以下的代碼來舉行處置懲罰:
self.addEventListener('notificationclick', function(event) {
console.log('[Service Worker] Notification click Received.');
event.notification.close();
event.waitUntil(clients.openWindow('https://developers.google.com/web/'));
});
總結
nodejs 可以運用這裏的庫來構建推送效勞器。
做一個網頁音訊推送所須要的前提即:
- 音訊推送效勞器(挪用音訊推送效勞及天生 VAPID 公鑰和私鑰對)。
- 搜檢瀏覽器端兼容性,獵取受權,運用音訊推送效勞器天生的公鑰並天生定閱對象,保留該定閱對象到推送效勞器上面。
- 音訊推送效勞(第三方效勞)。
一張流程圖來示意吧: