【问题标题】:Node EventEmitter manage listener poolNode EventEmitter 管理监听器池
【发布时间】:2019-12-27 09:56:12
【问题描述】:

我正在尝试定期通知所有客户端体育比赛的变化,为此我在 node.js 中使用 Eventemitter。通知工作正常,我遇到的问题是,如果客户端关闭/刷新浏览器窗口,我应该删除服务器上的侦听器并减少侦听器池,否则我很容易遇到内存泄漏警告。

代码:

const EventEmitter = require('events');
const Stream = new EventEmitter();

exports.getScheduleUpdates = async (req, res) => {
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        Connection: 'keep-alive'
    });

    Stream.on('push', (data) => {
        let isAlive = res.write(`data: ${JSON.stringify(data)}\n\n`);
        if (!isAlive) {
            console.log("Should terminate");
        }
        console.log(isAlive);
    });
}

setInterval(() => {
    Stream.emit('push', { match: 'sending some data' });
}, 10000);

当我在本地运行它并刷新浏览器例如 2 次时,该事件为 3 个客户端触发,其中 2 个已关闭并且 res.write 返回 false。

在 Google 的帮助下我做到了这一点,但我不知道如何处理事件的侦听器池并在 isAlive 标志为 false 时将其删除。不是 100% 确定依赖 res.write 返回值是否正确。

谢谢

【问题讨论】:

    标签: node.js server-sent-events eventemitter


    【解决方案1】:

    最后,我找到了这个教程: https://alligator.io/nodejs/server-sent-events-build-realtime-app/

    这最终对我的情况很有效。

    let connectedClients = [];
    exports.getScheduleUpdates = async (req, res) => {
        res.writeHead(200, {
            'Content-Type': 'text/event-stream',
            'Cache-Control': 'no-cache',
            Connection: 'keep-alive'
        });
    
        const clientId = Date.now();
        const newclient = {
            id: clientId,
            res
        }
        connectedClients.push(newclient);
    
        req.on('close', () => {
            connectedClients = connectedClients.filter(c => c.id !== clientId);
        });
    }
    
    function sendScheduleUpdates(changesToSend) {
        connectedClients.forEach(client => {
            client.res.write(`data: ${JSON.stringify(changesToSend)}\n\n`);
        });
    }
    
    setInterval(() => {
        sendScheduleUpdates([{ match: 'sending some data' }]);
    }, 10000);
    

    关闭旧的、未使用的响应在 res.on('close', () => {...}) 部分完成。

    【讨论】:

      猜你喜欢
      • 2014-06-06
      • 1970-01-01
      • 2018-10-07
      • 2013-04-08
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      相关资源
      最近更新 更多