我正在 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();
})
}
答案 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.connection
和response
是相同的对象,那么这是相同的代码,因此根本不特定于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)。