使用Node.JS,MongoDB和Socket.IO的实时多人游戏:游戏循环和asynchronous调用

我目前正在使用Node.JS,MongoDB和Socket.IO构buildHTML5游戏。 这个项目的目的不是真的创造一个完整的,完全可玩的游戏,而是理解和实现多人游戏编程的一些基本概念,并习惯于MongoDB。

这是我所使用的基本服务器架构。 服务器通过Socket.IO监听客户端,每次接收到消息时,都会将其推送到队列中。 每当玩家想要移动时都会收到消息,或者以某种方式有效地改变游戏。 我留的很模糊,因为向你详细说明这个游戏是什么并不重要。 所以服务器接收来自所有客户端的消息并将其保存在内存中一段时间​​。

每隔50ms,服务器按顺序处理队列中的所有消息,并使游戏状态前进,向客户端广播更改,然后清空队列并开始再次监听客户端。

我在构build这个游戏循环时遇到了一些困难,因为我不确定MongoDB是什么,如果它及时做到,所有的调用都是纯asynchronous的。 让我们说下面的代码是在我的游戏循环,这是我的顾虑:

for (var i=0; i<queue.length; i++) { if(queue[i].message.type === "move") { //The server has first to ensure that the player can effectively move, //thus making a query to MongoDB. Once the result has been retrieved, //the server makes an update in MongoDB with the new player position } //At this point, due to the async nature of MongoDB, //I cannot ensure that the queries have been executed nor that the message was effectively handled } //Here again, I cannot ensure that the game state gracefully advanced //and then I cannot broadcast it. 

我认为游戏循环必须是连续的,但是我不确定是否可以使用MongoDB来做到这一点,我不确定MongoDB是否适合这个工作。

我使用MongoDB的官方Node.JS驱动程序,因为我对嵌套文档比对象数据build模更感兴趣。

在这种情况下,你有没有build立一个顺序游戏循环的线索? 还是我在使用MongoDB的目的之外?

看起来很简单。

解决方法是不要使用for循环,因为您只想在前一个消息完成之后开始处理下一个消息。 为此,使用像asynceachSeries函数这样的库可能更容易。

https://github.com/caolan/async#each

 async.eachSeries(queue, processMessage, allDone); function processMessage(message, callback) { // do stuff with message, don't forget to call callback when you have complete all async calls and are done processing the message! // eg if(message.type === "move") { mongo.insert({player: message.player, x:message.x, y:message.y}, function (err, res) { // error check etc callback(); } } } function allDone() { // called when all messages have been proccessed! // setTimeout(processNewQueue, 50); }