服务器发送的事件为单个客户端创建了太多侦听器 [英] server sent events creates way too many listeners for single client

查看:222
本文介绍了服务器发送的事件为单个客户端创建了太多侦听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using server sent events in MEAN stack. I am able to push data from server to client whenever required.

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

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).

多个侦听器.

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

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.

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

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();
    })
}

推荐答案

当客户端关闭套接字时,必须关闭正在为其服务的服务器端响应对象.

When the client closes the socket, you must close the server side response object that was servicing it.

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

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.");
  });

那是从我的书的第25页中复制的,该书是带有HTML5 SSE的数据推送应用.

That was copied from p.25 of my book, Data Push Apps with HTML5 SSE.

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

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();
  });

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

Assuming request.connection and response are the same object, then this is the same code, and therefore not specific to Express at all.

基于相关代码的更新

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

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);
  })

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

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

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).

这篇关于服务器发送的事件为单个客户端创建了太多侦听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆