Interaction between expressjs, socket.io and Event

2019-07-31 01:05发布

问题:

I have a server setup using expressjs which communicates with the front end clients using socket.io. The server runs on the raspberry pi and provides a backend to control mplayer player for my music library using the mplayer nodejs module.

Most of the actions to update the clients on the front end are taken based on events emitted by the mplayer EventEmitter module. For example :

When a command to stop the player is issued as player.stop() the EventEmitter instance of the player emits 'stop' event.

The server then listens for this event as follows : player.on('stop', socket.emit('stop'));

The issue that I have noticed is as more clients connect to the server over socket io each client creates a listener for the mplayer EventEmitter 'stop' event !! So for example if there were 3 clients, I would tend to receive 3 'stop' events from the player EventEmitter and consequently send 3 'stop' events to my front end clients.

My question is how can I ensure that only one listener is created for the player event? Why does every client bind itself as a listener to the EventEmitter event ?

My server side socketio setup looks as follows :

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
    }

Console output when 3 clients are connected, on receiving the 'stop' event :

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

This leads me to send 3 'next' events to be send to all my clients.

MPlayer nodejs looks like this :

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

mplayer for nodejs

On further investigation through stackoverflow it seems similar to this question : Local eventEmitter listening to global eventEmitter

But the solution provided in the comments doesn't make sense to me because of the use of addListener and removeListener ?? Can someone break it down for me and explain how I would achieve what is mentioned there ?

回答1:

The problem seemed to be this piece of code

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
    }

Having the player inside the connection block caused every client to bind to the player as a listener. On moving all player event handling in to the global scope the problem seems to have gone.