问题
I am using server sent events in MEAN stack. I am able to push data from server to client whenever required.
But one thing i noticed that even if i am the only client hitting the server. There are multiple listeners for me and events are broadcast to say 40 listeners(if i wait long enough for the client to reconnect 40 times).
Multiple listeners are also created when user reloads.
How can i limit the listeners to say 1 listener to per event per client. Is this even possible with server sent events.
I am trying to keep the connection open as long as the user is using the website and close only when the browser/tab is closed or clients request a reload.
NOTE : stream is an EventEmitter object which I use to pass events so that the required changes can be monitored and appropriate data can be send through server sent events.
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:
When the client closes the socket, you must close the server side response object that was servicing it.
At least when using the http
package directly, the code is something like this:
request.connection.on("close", function(){
response.end();
//Any other clean up, e.g. clearInterval() for any timers.
console.log("Client closed connection. Aborting.");
});
That was copied from p.25 of my book, Data Push Apps with HTML5 SSE.
At https://stackoverflow.com/a/59041709/841830 there is an example for Express.js, which they write it as:
response.on('close', () => {
console.log('client dropped me');
//Any other clean up
response.end();
});
Assuming request.connection
and response
are the same object, then this is the same code, and therefore not specific to Express at all.
UPDATE based on code in question
Your stream.on()
calls are adding a listener to an event. They are therefore part of the "clean up" in you have to do when the client disconnects. I.e.
response.on('close', () => {
console.log('client dropped me');
response.end();
stream.off('event-L', eventLHandler);
stream.off('event-U', eventUHandler);
})
See https://nodejs.org/api/events.html#events_emitter_off_eventname_listener
Notice how you need to specify the event handler function, so cannot use anonymous functions. Refactor your code to have two event handlers (that take response as an arg).
来源:https://stackoverflow.com/questions/59751406/server-sent-events-creates-way-too-many-listeners-for-single-client