【问题标题】:Interaction between expressjs, socket.io and EventEmitter listenersexpressjs、socket.io 和 EventEmitter 监听器之间的交互
【发布时间】:2016-05-04 14:52:15
【问题描述】:

我有一个使用 expressjs 的服务器设置,它使用 socket.io 与前端客户端通信。服务器在树莓派上运行,并提供了一个后端来使用 mplayer nodejs 模块为我的音乐库控制 mplayer 播放器。

大多数更新前端客户端的操作都是基于 mplayer EventEmitter 模块发出的事件。例如:

当以player.stop() 发出停止播放器的命令时,播放器的EventEmitter 实例会发出'stop' 事件。

然后服务器按如下方式侦听此事件: player.on('stop', socket.emit('stop'));

我注意到的问题是,随着越来越多的客户端通过套接字 io 连接到服务器,每个客户端都会为 mplayer EventEmitter 'stop' 事件创建一个侦听器!因此,例如,如果有 3 个客户端,我会倾向于从玩家 EventEmitter 接收 3 个'stop' 事件,然后向我的前端客户端发送 3 个'stop' 事件。

我的问题是如何确保只为玩家事件创建一个侦听器?为什么每个客户端都将自己绑定为 EventEmitter 事件的侦听器?

我的服务器端 socketio 设置如下:

io.on('connection', function(socket) {
    console.log('a user connected @ ' + socket.id);

    ///// Listen for player to successfully stop playing or when EOF is reached
    player.on('stop', function() {
        console.log("Received Stop Event From Player");
        socket.emit('song:next'); //Play next song
    }

3 个客户端连接时的控制台输出,接收到'stop' 事件:

Received Stop Event From Player
Received Stop Event From Player
Received Stop Event From Player

这导致我发送 3 个'next' 事件以发送给我的所有客户。

MPlayer nodejs 看起来像这样:

this.player.on('playstop', function() {
    if(options.verbose) {
        console.log('player.stop');
    }
    this.emit('stop')
}.bind(this));

mplayer for nodejs

通过 stackoverflow 进一步调查,它似乎类似于这个问题: Local eventEmitter listening to global eventEmitter

但是由于使用了 addListener 和 removeListener,cmets 中提供的解决方案对我没有意义?有人可以为我分解并解释我将如何实现其中提到的内容吗?

【问题讨论】:

  • 您将需要实现一个 removeListener 函数,就像您提到的问题一样。但这只会在用户断开连接时调用。我还认为每个用户都需要一个特定的套接字事件。您可以为此使用socket.id。因此,对于您发出和侦听的所有事件,您将在末尾附加 socket.id
  • 如果玩家知道向它发送停止命令的套接字 id 会更有意义吗?这样,在玩家的emit('stop') 中,我可以将id 作为数据emit('stop', {id: clientId}) 发送,而服务器套接字将emit('next') 仅用于该clientId?
  • 是的,这样会更有意义。您应该这样做,这样您就不必绑定所有这些事件。绑定一个事件 => 传递 id => 使用 id 执行用户特定的操作。 ??????????
  • 非常感谢。我想我将使用一个 masterClientId 将下一个事件发送到前端。

标签: node.js sockets express eventemitter mplayer


【解决方案1】:

问题似乎是这段代码

io.on('connection', function(socket) {
    console.log('a user connected @ ' + socket.id);

    ///// Listen for player to successfully stop playing or when EOF is reached
    player.on('stop', function() {
        console.log("Received Stop Event From Player");
        socket.emit('song:next'); //Play next song
    }

将播放器放在连接块中会导致每个客户端都作为侦听器绑定到播放器。将所有玩家事件处理移至全局范围后,问题似乎已经消失。

【讨论】:

    猜你喜欢
    • 2017-06-03
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 2018-05-13
    • 2014-11-03
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多