首頁 > web前端 > js教程 > 使用 JavaScript 實作推播通知:生產級方法

使用 JavaScript 實作推播通知:生產級方法

WBOY
發布: 2024-08-17 13:05:02
原創
489 人瀏覽過

Implementing Push Notifications Using JavaScript: A Production-Grade Approach

在這篇文章中,您將學習如何透過遵循生產級最佳實踐來使用 JavaScript 實現推播通知。最好的事情之一是我也會提供一個資料夾結構,以便您可以輕鬆地設定您的專案。

在現實世界的應用程式中設定推播通知需要仔細規劃。我將向您展示如何在專業的 Node.js 應用程式中建立此功能。我們將介紹重要的部分,例如如何組織您的程式碼、確保內容安全,並確保即使您的應用程式不斷成長,它也能正常運作。

首先,您需要一個函式庫來幫助您從 Node.js 伺服器發送推播通知。 web-push 函式庫提供了用於傳送通知和管理必要金鑰的工具。

1. 推播通知:專案結構

首先,讓我們設定專案結構以維護乾淨且可擴展的程式碼庫:

/notification-service
├── /config
│   ├── default.js
│   └── production.js
├── /controllers
│   └── notificationController.js
├── /models
│   └── user.js
├── /routes
│   └── notificationRoutes.js
├── /services
│   ├── notificationService.js
│   ├── subscriptionService.js
│   └── webPushService.js
├── /utils
│   └── errorHandler.js
├── /tests
│   └── notification.test.js
├── app.js
├── package.json
├── .env
└── README.md
登入後複製

所需的 NPM 包

在深入實施之前,請確保您已安裝以下 NPM 軟體包:

  • express:一個最小且靈活的 Node.js Web 應用程式框架。
  • mongoose:用於 MongoDB 和 Node.js 的 ODM(物件資料建模)庫。
  • web-push:使用 Web 推播協定傳送推播通知的函式庫。
  • dotenv:一個零依賴模組,從 .env 檔案載入環境變數。
  • supertest:用於在 Node.js 中測試 HTTP 斷言的函式庫。

使用 npm 安裝這些套件:

bash

npm install express mongoose web-push dotenv supertest
登入後複製

2. 推播通知:專案配置

為不同環境(例如開發、生產)建立設定檔。這些文件儲存特定於環境的設定。

// /config/default.js
module.exports = {
    server: {
        port: 3000,
        env: 'development'
    },
    pushNotifications: {
        publicVapidKey: process.env.VAPID_PUBLIC_KEY,
        privateVapidKey: process.env.VAPID_PRIVATE_KEY,
        gcmApiKey: process.env.GCM_API_KEY
    },
    db: {
        uri: process.env.MONGO_URI
    }
};
登入後複製
// /config/production.js
module.exports = {
    server: {
        port: process.env.PORT || 3000,
        env: 'production'
    },
    // Same structure as default, with production-specific values
};
登入後複製

3. 資料庫建模

使用 Mongoose 定義您的使用者架構和通知訂閱。

// /models/user.js
const mongoose = require('mongoose');

const subscriptionSchema = new mongoose.Schema({
    endpoint: String,
    keys: {
        p256dh: String,
        auth: String
    }
});

const userSchema = new mongoose.Schema({
    email: { type: String, required: true, unique: true },
    subscriptions: [subscriptionSchema],
    preferences: {
        pushNotifications: { type: Boolean, default: true }
    }
});

module.exports = mongoose.model('User', userSchema);
登入後複製

4. 通知服務

將處理通知的邏輯模組化到服務中。

// /services/webPushService.js
const webPush = require('web-push');
const config = require('config');

webPush.setVapidDetails(
    'mailto:example@yourdomain.org',
    config.get('pushNotifications.publicVapidKey'),
    config.get('pushNotifications.privateVapidKey')
);

module.exports = {
    sendNotification: async (subscription, payload) => {
        try {
            await webPush.sendNotification(subscription, JSON.stringify(payload));
        } catch (error) {
            console.error('Error sending notification', error);
        }
    }
};
登入後複製
// /services/notificationService.js
const User = require('../models/user');
const webPushService = require('./webPushService');

module.exports = {
    sendPushNotifications: async (userId, payload) => {
        const user = await User.findById(userId);
        if (user && user.preferences.pushNotifications) {
            user.subscriptions.forEach(subscription => {
                webPushService.sendNotification(subscription, payload);
            });
        }
    }
};
登入後複製

5. 控制器邏輯

處理 API 路由並整合服務。

// /controllers/notificationController.js
const notificationService = require('../services/notificationService');

exports.sendNotification = async (req, res, next) => {
    try {
        const { userId, title, body } = req.body;
        const payload = { title, body };
        await notificationService.sendPushNotifications(userId, payload);
        res.status(200).json({ message: 'Notification sent successfully' });
    } catch (error) {
        next(error);
    }
};
登入後複製

6. 路由

為您的 API 設定路由。

// /routes/notificationRoutes.js
const express = require('express');
const router = express.Router();
const notificationController = require('../controllers/notificationController');

router.post('/send', notificationController.sendNotification);

module.exports = router;
登入後複製

7. 錯誤處理

集中錯誤處理以確保應用程式不會崩潰。

// /utils/errorHandler.js
module.exports = (err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send({ error: 'Something went wrong!' });
};
登入後複製

8. 應用程式入口點

初始化應用程式並連接到資料庫。

// app.js
const express = require('express');
const mongoose = require('mongoose');
const config = require('config');
const notificationRoutes = require('./routes/notificationRoutes');
const errorHandler = require('./utils/errorHandler');

const app = express();

app.use(express.json());
app.use('/api/notifications', notificationRoutes);
app.use(errorHandler);

mongoose.connect(config.get('db.uri'), {
    useNewUrlParser: true,
    useUnifiedTopology: true
})
    .then(() => console.log('MongoDB connected...'))
    .catch(err => console.error('MongoDB connection error:', err));

const PORT = config.get('server.port');
app.listen(PORT, () => console.log(`Server running in ${config.get('server.env')} mode on port ${PORT}`));
登入後複製

9. 安全實務

  • 環境變數:在環境變數中儲存 API 金鑰和資料庫 URI 等敏感資訊。
  • HTTPS:透過 HTTPS 為您的應用程式提供服務,以保護客戶端和伺服器之間的通訊。
  • 內容安全策略 (CSP):實作 CSP 標頭以防止跨站腳本 (XSS) 攻擊。
  • 速率限制:使用express-rate-limit等中間件來保護您的API免受暴力攻擊。

10. 測試

編寫測試以確保您的服務在各種條件下按預期工作。

// /tests/notification.test.js
const request = require('supertest');
const app = require('../app');

describe('Notification API', () => {
    it('should send a notification', async () => {
        const res = await request(app)
            .post('/api/notifications/send')
            .send({ userId: 'someUserId', title: 'Test', body: 'This is a test' });
        expect(res.statusCode).toEqual(200);
        expect(res.body.message).toBe('Notification sent successfully');
    });
});
登入後複製

11. 部署到生產環境

  • CI/CD 管道:使用 Jenkins、GitHub Actions 或 GitLab CI 等工具設定 CI/CD 管道,以自動測試、建置和部署應用程式。
  • 容器化:對您的應用程式進行 Docker 化,以確保不同環境之間的一致性。
  • 監控:使用 Prometheus 和 Grafana 等監控工具來追蹤應用程式的運作狀況和效能。

12. 縮放

  • 水平擴充:在負載平衡器後面部署服務的多個執行個體以處理高流量。
  • 資料庫擴充:在 MongoDB 中實作分片或副本集,以實現資料庫的水平擴充。

這種生產級設定可確保您的推播通知系統可擴充、安全且可維護。該程式碼的組織方式是為了支援輕鬆測試、部署和監控,遵循行業最佳實踐。如果您還有任何疑問或需要具體實施細節,請隨時詢問!

以上是使用 JavaScript 實作推播通知:生產級方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板