服务器发送的事件为单个客户端创建了太多的监听器

时间:2020-01-15 12:24:31

标签: express angular7 server-sent-events eventemitter eventsource

我正在 MEAN 堆栈中使用服务器发送的事件。 我能够在需要时将数据从服务器推送到客户端。

但是有一件事,我注意到即使我是打服务器的唯一客户端。我有多个听众,广播的事件说 40个听众如果我等待足够长的时间让客户端重新连接40次)。

当用户重新加载时,还会创建

多个侦听器

我如何限制听众说每个客户每个事件只能听1个听众。服务器发送事件甚至有可能做到这一点。

只要用户正在使用网站,我就会尝试保持连接打开,并且仅在关闭浏览器/选项卡或客户端请求重新加载时关闭。

注意是一个 EventEmitter 对象,我用于传递事件,以便可以进行所需的更改受到监视,并可以通过服务器发送的事件发送适当的数据。

const function = async (request: Request, response: Response) => {
    console.log("client connected to broadcasting channel")
    console.log("listeners : " , stream.listenerCount('event-L'))
    response.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        "X-Accel-Buffering": "no"
    });
    response.flushHeaders();

    stream.on('event-L', (event, data) => {
            console.log("Broadcasting event-L")
            response.write('event: ' + event + '\n' + 'data:' + JSON.stringify(data) + '\n\n')
        }
    })


    stream.on('event-U', (event, data) => {
            console.log("Broadcasting event-U.")
            response.write('event: ' + event + '\n' + 'data:' + JSON.stringify(data) + '\n\n')
        }

    })

    response.on('close', () => {
        console.log('client dropped me');
        response.end();
    })
}

1 个答案:

答案 0 :(得分:0)

当客户端关闭套接字时,您必须关闭为它提供服务的服务器端响应对象。

至少直接使用http软件包时,代码是这样的:

request.connection.on("close", function(){
  response.end();
  //Any other clean up, e.g. clearInterval() for any timers.
  console.log("Client closed connection. Aborting.");
  });

它是从我的书第25页的“带有HTML5 SSE的数据推送应用程序”中复制的。

https://stackoverflow.com/a/59041709/841830,有一个Express.js的示例,他们将其写为:

response.on('close', () => {
  console.log('client dropped me');
  //Any other clean up
  response.end();
  });

假设request.connectionresponse是相同的对象,那么这是相同的代码,因此根本不特定于Express。

基于相关代码的更新

您的stream.on()呼叫正在向事件添加侦听器。因此,它们是客户端断开连接时必须执行的“清理”的一部分。即

response.on('close', () => {
  console.log('client dropped me');
  response.end();
  stream.off('event-L', eventLHandler);
  stream.off('event-U', eventUHandler);
  })

请参见https://nodejs.org/api/events.html#events_emitter_off_eventname_listener

请注意您需要如何指定事件处理函数,因此不能使用匿名函数。重构代码,使其具有两个事件处理程序(将响应作为arg)。

相关问题