本程式碼研究室會逐步說明如何建構推播通知伺服器。 完成程式碼研究室後,您的伺服器將具有:
- 追蹤推播通知訂閱 (即伺服器會建立 新的資料庫記錄下來 在用戶端停用時刪除現有的資料庫記錄)
- 將推播通知傳送至單一用戶端
- 傳送推播通知給所有已訂閱的用戶端
本程式碼研究室著重於協助您從工作中學習,不會 一些概念退房日 推播通知的運作方式 瞭解推播通知的概念
本程式碼研究室的用戶端程式碼已完成。 。如要瞭解 推播通知用戶端,請參閱「程式碼研究室:建構推播通知 用戶端。
請參閱 push-notifications-server-codelab-complete 的說明 (資料來源) 就能看到完整程式碼
瀏覽器相容性
本程式碼研究室介紹的作業系統和瀏覽器組合如下:
- Windows:Chrome、Edge
- macOS:Chrome、Firefox
- Android:Chrome、Firefox
已知本程式碼研究室「無法」與下列作業系統搭配使用 (或作業系統和瀏覽器組合):
- macOS:Brave、Edge、Safari
- iOS
應用程式堆疊
- 伺服器是以 Express.js 為基礎。
- web-push Node.js 程式庫 會處理所有推播通知邏輯
- 訂閱資料會使用 lowdb 寫入 JSON 檔案。
您不必使用上述任何技術導入推播通知。 我們之所以選擇這些技術,是因為這類技術可提供可靠的程式碼研究室體驗。
設定
取得程式碼的可編輯副本
這類操作說明右側的程式碼編輯器會稱為 Glitch UI。
- 按一下「Remix to Edit」即可編輯專案。
設定驗證方法
必須先完成設定,才能使用推播通知 驗證金鑰和用戶端。 請參閱「簽署網路推送通訊協定要求」一節。 瞭解原因。
- 依序點選「Tools」和「Terminal」,開啟 Glitch 終端機。
- 在終端機中執行
npx web-push generate-vapid-keys
。複製私密金鑰 和公開金鑰值 - 開啟「
.env
」,並更新「VAPID_PUBLIC_KEY
」和「VAPID_PRIVATE_KEY
」。組合VAPID_SUBJECT
到mailto:test@test.test
。這些值全都應包裝 。更新完成後,.env
檔案應該會顯示 類似這樣:
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
- 關閉 Glitch 終端機。
- 開啟
public/index.js
。 - 將
VAPID_PUBLIC_KEY_VALUE_HERE
替換為公開金鑰的值。
管理訂閱項目
您的用戶端會處理大部分的訂閱流程。主要 伺服器使用者必須先儲存新的推播通知訂閱項目 和刪除舊的訂閱這些訂閱方案能讓你 。 請參閱「訂閱用戶端以接收推播通知」 瞭解訂閱流程的詳細資訊
儲存新的訂閱資訊
- 如要預覽網站,請按下「查看應用程式」。然後按下
全螢幕
。
- 按一下「應用程式」分頁中的「註冊 Service Worker」。在狀態方塊中 會看到類似以下的訊息:
Service worker registered. Scope: https://desert-cactus-sunset.glitch.me/
- 在應用程式分頁中,按一下「訂閱推送」。你的瀏覽器或作業系統 詢問是否要允許網站傳送推播通知給你。按一下「允許」 (或其他項目) 您瀏覽器/OS 使用的對應語句)。狀態方塊中應會顯示類似訊息 改為:
Service worker subscribed to push. Endpoint: https://fcm.googleapis.com/fcm/send/…
- 在 Glitch UI 中,按一下「View Source」,返回程式碼。
- 依序點選「Tools」和「Logs」,開啟 Glitch 記錄。個人中心
您應該會看到
/add-subscription
,後面接著一些資料。/add-subscription
是 用戶端傳送 發布 要求訂閱推播通知時發出的要求。這些資料會用於 是您必須儲存的用戶端訂閱資訊。 - 開啟
server.js
。 - 使用下列程式碼更新
/add-subscription
路徑處理常式邏輯:
app.post('/add-subscription', (request, response) => {
console.log('/add-subscription');
console.log(request.body);
console.log(`Subscribing ${request.body.endpoint}`);
db.get('subscriptions')
.push(request.body)
.write();
response.sendStatus(200);
});
刪除舊的訂閱資訊
- 返回「應用程式」分頁。
- 按一下「取消訂閱推送通知」。
- 再次查看「毛刺記錄」。您應該會看到
/remove-subscription
追蹤 而非用戶端的訂閱資訊 - 使用下列程式碼更新
/remove-subscription
路徑處理常式邏輯:
app.post('/remove-subscription', (request, response) => {
console.log('/remove-subscription');
console.log(request.body);
console.log(`Unsubscribing ${request.body.endpoint}`);
db.get('subscriptions')
.remove({endpoint: request.body.endpoint})
.write();
response.sendStatus(200);
});
傳送通知
如「傳送推送訊息」一節所述, 您的伺服器未實際傳送推送訊息給用戶端。 而是依賴推送服務來進行。基本上, 將訊息推送到客戶的流程 Service 要求 (網路推送通訊協定要求) 傳送至網路服務 (推送服務) 您為使用者所用的瀏覽器供應商所有。
- 使用下列程式碼更新
/notify-me
路徑處理常式邏輯:
app.post('/notify-me', (request, response) => {
console.log('/notify-me');
console.log(request.body);
console.log(`Notifying ${request.body.endpoint}`);
const subscription =
db.get('subscriptions').find({endpoint: request.body.endpoint}).value();
sendNotifications([subscription]);
response.sendStatus(200);
});
- 使用下列程式碼更新
sendNotifications()
函式:
function sendNotifications(subscriptions) {
// TODO
// Create the notification content.
const notification = JSON.stringify({
title: "Hello, Notifications!",
options: {
body: `ID: ${Math.floor(Math.random() * 100)}`
}
});
// Customize how the push service should attempt to deliver the push message.
// And provide authentication information.
const options = {
TTL: 10000,
vapidDetails: vapidDetails
};
// Send a push message to each client specified in the subscriptions array.
subscriptions.forEach(subscription => {
const endpoint = subscription.endpoint;
const id = endpoint.substr((endpoint.length - 8), endpoint.length);
webpush.sendNotification(subscription, notification, options)
.then(result => {
console.log(`Endpoint ID: ${id}`);
console.log(`Result: ${result.statusCode}`);
})
.catch(error => {
console.log(`Endpoint ID: ${id}`);
console.log(`Error: ${error} `);
});
});
}
- 使用下列程式碼更新
/notify-all
路徑處理常式邏輯:
app.post('/notify-all', (request, response) => {
console.log('/notify-all');
response.sendStatus(200);
console.log('Notifying all subscribers');
const subscriptions =
db.get('subscriptions').cloneDeep().value();
if (subscriptions.length > 0) {
sendNotifications(subscriptions);
response.sendStatus(200);
} else {
response.sendStatus(409);
}
});
- 返回「應用程式」分頁。
- 按一下 [取消訂閱推送通知],然後再次點選 [訂閱推送]。 這不是必要動作,因為如先前所說,Glitch 會重新啟動專案。 每次編輯程式碼,並將專案設定為在啟動時刪除資料庫。
- 按一下「通知我」。您應該會收到推播通知。標題應該
為
Hello, Notifications!
,而主體應為ID: <ID>
,其中<ID>
是 隨機數字 - 請在其他瀏覽器或裝置上開啟您的應用程式,並嘗試訂閱推播通知 然後按一下「全部通知」按鈕。您應該在 您所有訂閱的裝置 (亦即推播通知內文中的 ID 是一樣的)。
後續步驟
- 閱讀「推播通知總覽」一文 以便更加瞭解推播通知的運作方式。
- 查看「程式碼研究室:建構推播通知用戶端」 來瞭解如何建立會要求通知權限的用戶端、 接收推播通知,並使用 Service Worker 接收推播通知 推播通知,並將訊息顯示為通知。