2012-05-21 16 views
5

he construido un simple juego de varios jugadores matemáticas en tiempo real de meteoros que se puede probar aquí: http://mathplay.meteor.comLos clientes del juego multijugador de Meteor no se sincronizan. ¿Cómo depurar?

Al reproducir localmente (usando diferentes navegadores), todo funciona bien. Pero cuando juego en Internet con amigos, los clientes a menudo no se sincronizan: una pregunta que aparece como activa para un jugador en realidad ya está resuelta por otro jugador.

Supongo que algún código que debería ser de solo servidor se ejecuta en uno de los clientes. ¿Alguna sugerencia sobre cómo depurar este comportamiento?

Esto es lo que ocurre en el cliente cuando el usuario envía una respuesta:

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() desencadena esta en cliente y servidor:

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; 
}, 

código fuente completo está aquí por referencia: https://github.com/tomsoderlund/MathPlay

+0

Estoy un poco sorprendido por la respuesta negativa a su pregunta. Aunque, se redacta más como una solicitud de revisión de código que como una pregunta específica. Debes venir al canal de meteoros IRC, apuesto a que alguien estará feliz de hablar sobre tu error. – lashleigh

Respuesta

3

Su problema radica en esto:

callGetNewQuestion() desencadena esta en cliente y servidor

Esto generará un diferente _id debido a la diferencia de tiempo, así como una pregunta diferente que luego son reemplazados con aquella que genera el servidor. Sin embargo, esto podría no ser siempre el caso. Esto hace que sea muy fácil dejar que las cosas se desincronicen, simplemente porque su cliente está generando sus propias cosas.


Tendrá que encontrar un mejor enfoque para asegurarse de que el cliente genera los mismos datos que el servidor. Lo cual se puede hacer asegurándose de que un generador de números aleatorios se siembra de la misma manera y, por lo tanto, dará los mismos números aleatorios cada vez. Esto resolverá cualquier parpadeo porque los valores son diferentes.


Entonces, para el error real que se pueda no desee hacer esto:

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

Pero hacer esto en su lugar (sólo en el cliente, no hacer nada en el servidor):

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

de esta manera, se puede poner lo siguiente en un ayudante de plantilla:

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

En esencia, esto funcionará de forma reactiva en la Colección y no dependerá del valor de devolución.

Cuestiones relacionadas