Node.js expressjs、socket.io和EventEmitter侦听器之间的交互
我有一个使用expressjs的服务器设置,它使用socket.io与前端客户端进行通信。服务器运行在raspberry pi上,并提供一个后端,使用mplayer nodejs模块控制我的音乐库的mplayer播放器 在前端更新客户端的大多数操作都是基于mplayer 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('
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将下一个事件发送到前端。