Node.js expressjs、socket.io和EventEmitter侦听器之间的交互

Node.js expressjs、socket.io和EventEmitter侦听器之间的交互,node.js,sockets,express,eventemitter,mplayer,Node.js,Sockets,Express,Eventemitter,Mplayer,我有一个使用expressjs的服务器设置,它使用socket.io与前端客户端进行通信。服务器运行在raspberry pi上,并提供一个后端,使用mplayer nodejs模块控制我的音乐库的mplayer播放器 在前端更新客户端的大多数操作都是基于mplayer EventEmitter模块发出的事件执行的。例如: 当作为player.stop()发出停止播放机的命令时,播放机的EventEmitter实例将发出'stop'事件 然后,服务器侦听此事件,如下所示: player.on('

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

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

当作为
player.stop()
发出停止播放机的命令时,播放机的EventEmitter实例将发出
'stop'
事件

然后,服务器侦听此事件,如下所示:
player.on('stop',socket.emit('stop')

我注意到的一个问题是,随着越来越多的客户端通过套接字io连接到服务器,每个客户端都会为mplayer EventEmitter
'stop'
事件创建一个侦听器!!因此,例如,如果有3个客户端,我会倾向于从player 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 NodeJ如下所示:

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

通过stackoverflow进行的进一步调查似乎与此问题类似:

但是由于使用了addListener和RemovelListener,评论中提供的解决方案对我来说没有意义??有人能帮我把它分解一下,解释一下我将如何实现上面提到的目标吗


问题似乎在于这段代码

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
    }

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

问题似乎是这段代码

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
    }

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

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