半年前,我在node.js和socket.io中编写了一个小型多人游戏。现在我试图改进它,我的一个改进是将代码分解成模块(顺便说一下。我使用expressjs 4.4和socket.io 1.0)。我有一个玩家队列来处理连接玩家的顺序。一切都很顺利,直到我遇到socket.io:我想在播放器队列中处理(dis-)连接监听器,而我想把所有与游戏相关的监听器放在我的游戏模块中。我尝试了一些事情,包括Using socket.io from a module和What's the correct way to pass a Socket.IO socket between modules?,我没有把它带到工作中。目前我正在传递io对象:
io = require("socket.io")(server);
我错过了什么吗?
我的代码:
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;
并且为了完整性:
index.js (客户端)
define(["socketio"], function(io) {
var socket = io("/player");
socket.on("blub", function() {
console.log("blub");
});
setInterval(function() {
socket.emit("blub");
}, 1000);
});
答案 0 :(得分:0)
一年之后,我有时间清理并分享我在那段时间内获得的见解。
在整个项目中传播与socket.io相关的代码是糟糕的设计(或者来自任何其他库的代码)。如果您必须更改包装器库,则必须在代码库中的许多位置执行此操作。更好的方法是将socket.io的使用限制在一个薄层,在该薄层中完成与websockets之间的所有通信。从那以后,您将使用另一层消息:您自己的消息。 Node.js的&#39;自己的EventEmitter是你工作所需要的一切。