I'm writing a game in NodeJS with Socket.io. I have a Player
class where users are able to log in and out of the game. However when a client logs out of the game, and re-joins their old event listeners are firing twice.
I tried looking at this question, but it doesn't seem to work as it still produces duplicate output.
My code:
Output:
[+] Player [OZYaW0Ncrfg21NJDAAAB] has logged in.
[+] Player moved to [10,111]
[-] Player [OZYaW0Ncrfg21NJDAAAB] has logged out.
[+] Player moved to [10,111]
[+] Player [OZYaW0Ncrfg21NJDAAAB] has logged in.
[+] Player moved to [10,111]
[+] Player moved to [10,111] <-- this should not happen!
[-] Player [OZYaW0Ncrfg21NJDAAAB] has logged out.
client.js
var socket = io('http://localhost:8080/');
socket.emit('player.login');
socket.emit('player.move', [10, 111]);
socket.emit('player.logout');
socket.emit('player.move', [10, 111]);
socket.emit('player.login');
socket.emit('player.move', [10, 111]);
socket.emit('player.logout');
main.js
var io = require('socket.io')(8080);
var Player = require('./Player');
// All players
var players = {};
io.on('connection', function(socket) {
// On login
socket.on('player.login', function() {
players[socket.id] = new Player(socket);
console.log('[+] Player [' + socket.id + '] has logged in.');
});
// On logout
socket.on('player.logout', function() {
delete players[socket.id];
console.log('[-] Player [' + socket.id + '] has logged out.');
});
});
Player.js
/**
* Player class
* @param socket
* @constructor
*/
function Player(socket) {
this.socket = socket;
this.position = {x : 0, y : 0};
this.__bind();
}
/**
* Move a player
* @param {Array} position
*/
Player.prototype.move = function(position) {
this.position.x = position[0];
this.position.y = position[1];
console.log("[+] Player moved to [" + position[0] + ',' + position[1] + ']');
};
/**
* Add event listeners
* @private
*/
Player.prototype.__bind = function() {
this.socket.on('player.move', this.move.bind(this));
this.socket.on('player.logout', this.__unbind.bind(this));
};
/**
* Remove event listeners
* @private
*/
Player.prototype.__unbind = function() {
this.socket.removeListener('player.move', this.move);
};
// Exports
module.exports = Player;