server sent events creates way too many listeners for single client

家住魔仙堡 提交于 2020-02-05 03:51:56

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!