如何停止 Node.JS 通知流?

Posted

技术标签:

【中文标题】如何停止 Node.JS 通知流?【英文标题】:How to stop Node.JS notification flow? 【发布时间】:2018-06-26 18:45:09 【问题描述】:

我正在试验从Node.js 应用程序发送的推送通知。通过一些教程和示例,我现在有了一个可以开始工作的迷你应用程序。

它的作用非常基本,当它加载到浏览器中时,每十五秒触发一次通知,用户每次都会看到一条消息弹出。

问题来了:我应该如何停止通知循环?

此时,即使我关闭网页,通知也会每隔 15 秒发出一次。

作为参考,我在这里放了两个相关文件:

index.js

const express = require('express'),
      webPush = require('web-push'),
      bodyParser = require('body-parser'),
      path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'client')));
app.use(bodyParser.json());

const privateVapIdKey = process.env.privVapIdKey,
      publicVapIdKey = process.env.pubVapIdKey;

webPush.setVapidDetails(
    'mailto:myemail@example.com',
    publicVapIdKey,privateVapIdKey);

// Subscribe Route.
app.post('/subscribe',(req,res) => 
    const subscription = req.body; // Get Push Subscription Object.
    res.status(201).json(); // Send 201. Resource created.

    // Do a lot of useful things ......
    .......
    // Create the PayLoad.
    const payload = JSON.stringify(
        title:'A big title!',
        ........
    );

    // Pass Object to sendNotification loop.
    const SECS = 15 * 1000;
    setInterval(() => 
        // Do a lot of useful things ......
        .......

        webPush.sendNotification(subscription,payload).catch(err => console.error(err));
    , SECS);

);

const port = 5003;

const PORT = process.env.PORT || port;
app.listen(PORT, () => console.log(`Listening on $ PORT `));

client.js

const publicVapIdKey = 'my-secret-3453754...pubVapIdKey';

// Chec for ServiceWorker.
if ('serviceWorker' in navigator) 
    send().catch(err => console.error(err));



// Register ServiceWorker, Register Push, Send Push.
async function send() 
    console.log("Registering ServiceWorker.");
    const register = await navigator.serviceWorker.register('/worker.js', 
        scope: "/"
    );
    console.log('ServiceWorker registered.');

    console.log("Registering Push.");
    //register.pushManager.uns
    const subscription = await register.pushManager.subscribe(
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(publicVapIdKey)
    );
    console.log('Push registered.');

    console.log("Sending Push.");
    await fetch('/subscribe', 
        method: 'POST',
        body: JSON.stringify(subscription),
        headers: 
            'content-type': 'application/json'
        
    );
    console.log('Push sent.');



function urlBase64ToUint8Array(base64String) 
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
      .replace(/\-/g, '+')
      .replace(/_/g, '/');

    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let i = 0; i < rawData.length; ++i) 
      outputArray[i] = rawData.charCodeAt(i);
    

    return outputArray;

我想我需要在

之后添加一个 /unsubscribe 路由

await fetch('/subscribe',

在 client.js 中。但我不是 100% 确定,如果这是要做的事情,我该如何编写代码。

【问题讨论】:

【参考方案1】:

您需要做的是跟踪您的setInterval 函数,然后像这样使用clearInterval 函数:

const SECS = 15 * 1000;
const notificationLoop = setInterval(() => 
        // Do a lot of useful things ......
        webPush.sendNotification(subscription,payload).catch(err => console.error(err));
    , SECS);

当你想停止它时:

clearInterval(notificationLoop);

更多关于clearInterval的信息

请务必保留您的 notificationLoop 的引用,以防止它未定义。

【讨论】:

您的建议很有趣,但是您提到的页面指的是在客户端工作的东西(给出的示例是一个计时器,带有一个停止它的按钮)。在我的情况下,通知是从服务器触发的。情况不同。 在阅读了相当多之后,我想我需要在现有的订阅功能之外添加一些取消订阅功能。但我不知道该怎么做。

以上是关于如何停止 Node.JS 通知流?的主要内容,如果未能解决你的问题,请参考以下文章

node.js 进程如何知道何时停止?

如何在 node.js 中集成 FCM 以进行推送通知?

Node.js 流如何工作?

node.js 和 PHP 之间如何通信?

如何通过 Node.js 上的推送通知实现一些复杂的行为

如何从 Node.js 中的 API 请求创建响应流?