我正在关注制作HTML5游戏的this教程。我想尝试混合节点以使其成为多人游戏。我在服务器上使用node.js(v0.10.4),在前端使用crafty.js。
我正在使用socket.io来发送和接收消息。现在只是我(不是多个客户)。发生的奇怪事情是来自服务器的消息似乎被多次发送。我在socket.io中启用了调试模式,但它似乎只发送了一次数据,但在前端数据似乎是以倍数形式进入。我在数据上设置了一个增量器,似乎增量器没有多次递增,而是我得到了相同数据的多个副本。
这是节点代码:
var http = require('http').createServer(handler),
static = require('node-static'),
io = require('socket.io').listen(http);
io.set('log level', 3);
http.listen(80);
//attach the socket to our server
var file = new static.Server(); //Create a file object so we can server the files in the correct folder
function handler(req, res) {
req.addListener('end', function() {
file.serve(req, res);
}).resume();
}
io.sockets.on('connection', function (socket) { //listen for any sockets that will come from the client
socket.on('collected', function(data) {
/**** here's where the data is being sent back to the client *****/
socket.emit('messageFromServer', { data: data.number });
});
});
以及这里的前端代码:
//messenger entity
Crafty.c('SendRecieveMessages',{
count: 0,
sendMessageToServer : function() {
console.log('got a village');
/**** Here's where we send the message to the server ****/
socket.emit('collected', { village : "The message went to the server and back. it's collected", number : this.count });
this.count++;
},
recieveMessageFromServer : function() {
socket.on('messageFromServer', function(data) {
/*** This data seems to be coming back or logging multiple times? ***/
console.log(data);
});
}
});
最后,这是调试过程中的屏幕截图。正如您所看到的,数字并不总是递增,它几乎看起来像数据被存储。谢谢!
答案 0 :(得分:6)
看起来每次拨打Crafty.c
时,recieveMessageFromServer()
也会被调用。每次调用recieveMessageFromServer
时,它都会在套接字上附加一个事件侦听器。这就是为什么第一次数据回来时你得到一份副本,然后第二次得到两份,第三次得到三份,依此类推。
您需要阻止多次调用recieveMessageFromServer
,或使用removeListener或removeAllListeners删除以前连接的侦听器。
答案 1 :(得分:0)
感谢@Bret Copeland帮我解决这个问题。正如他所指出的,每次调用socket.on()时,它似乎都会添加另一个监听器。为了防止这种情况......
我宣布了一个全局变量:
我在我的Game对象中声明了一个变量作为属性(在craftyjs中,所以在你的设置中使用你想要的任何东西)
Game = {
//lots of other code here...
//need this to use later for socket.io
send_message : true
}
然后编辑我的recieveMessageFromServer()函数来检查它是否可以发送消息:
recieveMessageFromServer : function() {
console.log('does this show up multiple times?');
/* Check whether the send_message is true before sending */
if (Game.send_message) {
socket.on('messageFromServer', function(data) {
console.log(data);
Game.send_message = false;
});
}
}