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

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

问题描述

我在 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.

注意:stream 是一个 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.");
  });

这是从我的书《Data Push Apps with HTML5 SSE》的第 25 页复制而来的.

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

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

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天全站免登陆