2012-05-21 56 views
5

我已经建立了流星简单的实时多人数学游戏,你可以在这里尝试:http://mathplay.meteor.com流星多人游戏客户端不同步 - 如何调试?

在本地播放(使用不同的浏览器),一切工作正常。但是当我和朋友在互联网上玩时,客户往往不同步:一名球员列出的问题实际上已经被另一名球员解决了。

我的猜测是,一些代码应该是仅服务器,而不是在其中一个客户端上执行。有关如何调试此行为的任何建议?

这里是在客户端上会发生什么,当用户提交一个答案:

Template.number_input.events[okcancel_events('#answertextbox')] = make_okcancel_handler({ 
    ok: function (text, event) { 
     question = Questions.findOne({ order_number: Session.get("current_question_order_number") }); 
     if (question.answer == document.getElementById('answertextbox').value) { 
      console.log('True'); 
      Questions.update(question._id, {$set: {text: question.text.substr(0, question.text.length - 1) + question.answer, player: Session.get("player_name")}}); 
      callGetNewQuestion(); 
     } 
     else { 
      console.log('False'); 
     } 
     document.getElementById('answertextbox').value = ""; 
     document.getElementById('answertextbox').focus(); 
    } 
}); 

callGetNewQuestion()触发该客户端和服务器上:

getNewQuestion: function() { 
    var nr1 = Math.round(Math.random() * 100); 
    var nr2 = Math.round(Math.random() * 100); 
    question_string = nr1 + " + " + nr2 + " = ?"; 
    question_answer = (nr1 + nr2); 
    current_order_number = Questions.find({}).count() + 1; 
    current_question_id = Questions.insert({ order_number: current_order_number, text: question_string, answer: question_answer }); 
    return Questions.findOne({_id: current_question_id});//current_question_id; 
}, 

完整的源代码是在这里以供参考: https://github.com/tomsoderlund/MathPlay

+0

我对你对问题的否定回答感到有点惊讶。尽管它更像是一个代码审查请求,而不是一个特定的问题。你应该来到流星irc频道,我敢打赌,有人会很乐意聊天你的bug。 – lashleigh

回答

3

你的问题出在这里:

callGetNewQuestion()触发该客户端和服务器上

这将生成一个不同_id因为定时差,以及其将然后得到与产生该服务器的一个替换一个不同的问题的。但是,情况并非总是如此。这使得事情变得非常容易,只是因为你的客户正在生成自己的东西。


您需要弄清楚确保客户端生成与服务器相同的数据的更好方法。可以通过确保随机数生成器以相同方式播种来完成,因此每次都会给出相同的随机数。这将解决任何闪烁,因为这些值是不同的。


然后,对于实际的错误,你可能要做到这一点:

return Questions.findOne({_id: current_question_id}); 

但做到这一点,而不是(仅在客户端上,执行服务器上的任何操作):

Session.set('current_order', current_order_number); // ORDER! Not the _id/question_id. 

这样,您可以将以下内容放在模板助手中:

return Questions.findOne({ order_number: Session.get('current_order') }); 

实质上,这将在收集中以被动方式工作,而不依赖于返回值。