最近,我一直在開發一個僅使用 Web API 從頭開始建立的新 webpush 套件。這使得(至少在理論上)直接從瀏覽器發送 Web Push 訊息成為可能。
這篇部落格文章旨在解釋什麼是 Web Push 協定及其工作原理
(RFC 8291) 以及如何使用我的庫發送 Web 推播訊息。
Web 推送協議是一種中間協議,允許應用程式向用戶代理(通常是瀏覽器)發送訊息。
它與伺服器發送事件(SSE)類似,訊息被推送到用戶代理,但它有不同的目的。 Web 推播訊息不需要網站作為服務工作者開啟一個選項卡
可以監聽推播訊息。它在後台運行。
Web Push 協議涉及三個參與者:
以下是它們之間互動的概述:
+-------+ +--------------+ +-------------+ | UA | | Push Service | | Application | +-------+ +--------------+ +-------------+ | | | | Setup | | |<====================>| | | Provide Subscription | |-------------------------------------------->| | | | : : : | | Push Message | | Push Message |<---------------------| |<---------------------| | | | |
由於多種原因需要中間推送服務。
首先,它減少了頻寬和電池使用量,因為用戶代理僅為所有網站維護一個連接,而不是每個網站一個連接。
它還提高了可擴展性和可靠性,因為主要瀏覽器的推播服務旨在處理數百萬用戶。由於在用戶代理離線時必須保留推播訊息,因此建置推播服務需要大量的工程、彈性且冗餘的基礎設施
最後,對於小型網路公司來說,建置、部署和維護自訂推送服務通常過於複雜且佔用資源。這會為大公司帶來不公平的競爭優勢,因為他們將擁有必要的資源來開發和完善自己的推播服務。
如果您是像我一樣注重隱私的用戶,請參閱中介服務
接收所有訊息都會引發危險訊號。為了解決這個問題,Web Push
訊息透過 HTTP 加密內容編碼進行保護(請參閱我的
http-ece 包),確保
敏感資訊仍然受到保護,任何第三方都無法讀取
過境服務。
您可能已經注意到設定箭頭與上面 ASCII 圖中的其他箭頭不同。這是因為設定階段依賴實作。所有主流瀏覽器都實作了 javascript
在
中推送 API
不同的方式。傳回標準
的 PushManager.subscribe() 方法
PushSubscription 已公開。
訂閱始終包含與推播訂閱關聯的唯一 URL 端點以及用於加密訊息的公鑰。
建立訂閱時,可能會提供一個可選的applicationServerKey來識別應用程式伺服器推播訊息。這是自願應用程式伺服器識別(VAPID)身份驗證方法
(RFC 8292)。 VAPID 金鑰用於減輕對推送服務的 DDOS 攻擊。此外,在應用程式伺服器和推播服務之間添加身份驗證可以降低洩漏訂閱端點的風險。由於這些原因,它們在 Firefox 中是強制性的。
第二步是將訂閱傳送到應用程式伺服器,以便它可以開始傳送訊息。
應用程式伺服器通常會將訂閱儲存在資料庫中以供日後重複使用。
最後,為了推播訊息,應用程式伺服器使用 vapid 驗證方案發送加密的 HTTP 請求,前提是提供了 applicationServerKey 來建立訂閱。
如果推播服務收到訊息時用戶代理程式在線,則
轉發。否則,它會被存儲,直到用戶代理上線或訊息過期。
當使用者代理程式收到訊息時,它會執行推播事件處理程序,該處理程序主要用於顯示通知,僅此而已。
首先,您必須產生 VAPID 金鑰,因為某些瀏覽器強制要求它們:
$ deno run https://raw.githubusercontent.com/negrel/webpush/master/cmd/generate-vapid-keys.ts
複製輸出並將其儲存到檔案中,無需再次產生 VAPID 金鑰。
在您的應用程式伺服器程式碼中,您可以如下載入它們:
import * as webpush from "jsr:@negrel/webpush"; // Read generated VAPID file. const vapidKeysJson = Deno.readTextFileSync("./path/to/vapid.json"); // Import VAPID keys. webpush.importVapidKeys(JSON.parse(vapidKeysJson));
然後,您需要建立一個ApplicationServer物件實例。
// adminEmail is used by Push services maintainer to contact you in case there // is problem with your application server. const adminEmail = "john@example.com"; // Create an application server object. const appServer = await webpush.ApplicationServer.new({ contactInformation: "mailto:" + adminEmail, vapidKeys, });
然後要發送推播訊息,只需建立一個 PushSubscriber 並呼叫其
pushMessage()/pushTextMessage()方法如下:
const subsribers = []; // HTTP handler for user agent sending their subscription. function subscribeHandler(req) { // Extract subscription send by user agent. const subscription = await req.json(); // Store subscription in db. // ... // Create a subscriber object. const sub = appServer.subscribe(subscription); // Store subscriber in memory. subscribers.push(sub); } // Helper method to send message to all subscribers. function broadcastMessage(msg) { for (const sub of subscribes) { sub.pushTextMessage(msg, {}); } }
就是這樣,您向訂閱者發送推播訊息!
webpush 儲存庫包含一個互動式範例,其中包含可以在本地運行的類似程式碼。它還包含客戶端 JavaScript 程式碼,所以一定要檢查一下!
以上是使用 Deno 發送 Web 推播訊息的詳細內容。更多資訊請關注PHP中文網其他相關文章!