Half a year ago I wrote a little multiplayer game in node.js and with socket.io. Now I'm trying to improve it and one of my improvements is breaking up the code into modules (btw. I'm using expressjs 4.4 and socket.io 1.0). I have a player queue which handles the order of the connected players. Everything went pretty fine until I got stuck with socket.io: I'd like to handle the (dis-)connection listeners in the player queue while I'd like to put all the game related listeners in my game module. I tried a couple of things including Using socket.io from a module and What's the correct way to pass a Socket.IO socket between modules? none of which I brought to work. Currently I'm passing the io object from:
io = require("socket.io")(server);
Am I missing something?
My code:
PlayerManager.js
var log = require("npmlog"),
Player = require("./Model/Player").Player;
var playerIo;
var PlayerManager = (function() {
var self;
function PlayerManager(eventEmitter, io) {
log.info("PlayerManager", "loading PlayerManager");
self = this;
this.eventEmitter = eventEmitter;
this.io = io;
this.playerQueue = [];
this.players = [];
this.setSocketListeners();
}
PlayerManager.prototype.setSocketListeners = function() {
log.info("PlayerManager", "loading SocketListeners");
playerIo = this.io.of("/player").on("connection", function(socket) {
log.info("PlayerManager", "Player " + socket.id + " has connected");
socket.on("disconnect", function() {
log.info("PlayerManager", "Player " + socket.id + " has disconnected.");
self.removePlayer(socket.id);
});
self.addPlayer(new Player(socket));
});
};
PlayerManager.prototype.addPlayer = function(player) {
log.info("PlayerManager", "Pushing Player " + player.socket.id + " to Queue. Current position: " + this.playerQueue.length);
this.playerQueue.push(player);
};
PlayerManager.prototype.removePlayer = function(id) {
log.info("PlayerManager", "Removing Player " + id + " from Queue");
var player = this.getPlayerById(id);
if (!player) {
return;
}
this.playerQueue.splice(this.playerQueue.indexOf(player), 1);
};
PlayerManager.prototype.getPlayers = function() {
log.info("PlayerManager", "Choosing players (length of queue: " + this.playerQueue.length + ")");
this.players = [];
if (this.playerQueue.length >= 1) { //should be changed to 2 in PROD
var player;
for (var i = 0; i < 4; ++i) {
player = this.playerQueue.shift();
if (player !== undefined && !player.socket.disconnected) {
player.socket.join("players");
this.players.push(player);
}
}
return this.players;
} else {
return false;
}
};
PlayerManager.prototype.onGameFinished = function() {
var player;
while (this.players && this.players.length > 0) {
player = this.players.shift();
player.socket.leave("players");
log.info("GameManager", "players size: " + self.players.length);
}
};
PlayerManager.prototype.getPlayerById = function(id) {
for (var i = 0; i < this.playerQueue.length; ++i) {
if (this.playerQueue[i].socket.id === id) {
return this.playerQueue[i];
}
}
return false;
};
return PlayerManager;
})();
exports = module.exports = PlayerManager;
Game.js
var log = require("npmlog");
var config = require("./config");
var Duck = require("./Model/Duck").Duck;
var Game = (function() {
var self;
function Game(eventEmitter, io, players) {
log.info("Game", "loading ...");
self = this;
this.io = io;
this.eventEmitter = eventEmitter;
this.players = players;
setInterval(function() {
self.io.to("players").emit("blub");
});
// ...
return Game;
})();
exports = module.exports = Game;
and for completeness:
index.js (the client)
define(["socketio"], function(io) {
var socket = io("/player");
socket.on("blub", function() {
console.log("blub");
});
setInterval(function() {
socket.emit("blub");
}, 1000);
});