2011-06-05 11 views
5

Imagina una pizarra multijugador donde varias personas pueden dibujar al mismo tiempo. Para hacerlo simple, digamos que hay un solo objeto en la pizarra que cualquier usuario puede mover o eliminar. No hay ninguna noción de objetos de propiedad del usuario (es decir, es importante que cualquier usuario pueda manipular cualquier objeto ... es una pizarra libre)Condición de carrera de la pizarra multijugador

Mi problema es este ... si dos usuarios intentan hacer una acción diferente sobre el objeto al mismo tiempo, es decir, uno lo elimina, el otro lo mueve, ¿qué ocurre?

En este momento, al dejar que los mensajes pasen desapercibidos.

Una idea era tener un control en el servidor que resuelva quién tiene el control del objeto, y no se permite que nada suceda al cliente hasta que se resuelva ese conflicto. La resolución de conflictos se puede basar en el orden de llegada.

Aunque esto puede suceder muy rápido, la pequeña demora (~ 50-300ms) es inaceptable ya que el movimiento debe ser instantáneo en el lado del cliente. Por ejemplo, en lugar de manipular objetos, piense en un bolígrafo. Para que haya un retraso hasta que ya hayan empezado a dibujar ... ¡no es bueno!

Otra idea era tener un botón de "control de solicitud", que solicita la extensión en el servidor para controlar ... la misma idea que antes, pero ahora no se sienten frustrados por el retraso inicial del dibujo con bolígrafo. Esto tampoco es tan bueno, ya que deben presionar ese botón hasta que puedan hacer cualquier cosa, y esta pizarra es realmente para niños ...

¿Alguna otra solución? :)

Respuesta

3

Este es un problema interesante que generalmente se resuelve mediante una combinación en las resoluciones del lado del cliente y del servidor. Si está familiarizado con WoW, especialmente en los días de lanzamiento inicial, recordará un bloqueo del servidor y todos continúan moviéndose. Esto lo hace el cliente gestionando movimientos predicativos y solicitando actualizaciones periódicas del servidor para la ubicación real y los valores de comportamiento.

Una idea similar debería ser aplicable a su problema. La resolución del servidor en una base f.c.f.s parece ideal. El problema que mencionas es la latencia que reduce la experiencia del usuario. Para eliminar esto, ¿por qué no darle al usuario control completo del lado del cliente y luego solicitar la actualización desde el servidor después de la operación? Entonces, si mueves un círculo hacia abajo 200px, y cambio el color a verde, ambos podemos ver el comportamiento instantáneo del lado del cliente, pero cuando sueltes el círculo también verás que se vuelve verde, como se indica a través del servidor.

El problema obvio para esto se produce cuando ambos usuarios cambian las mismas propiedades del objeto. En este punto, el sistema f.c.f.s deberá tomar una decisión sobre qué hacer en función del uso del cliente. ¿Debería realizar el delta neto en el objeto? ¿Debe notificar al usuario que otro usuario ha cambiado el objeto de una manera diferente? Esta es más una pregunta característica que una técnica.

+0

¡Me gusta cómo ha señalado que el conflicto solo existe para cambios de propiedad específicos! es decir, el color y la posición no son un conflicto, pero la posición y posición o posición y eliminación son ... – davidkomer

+0

Supongo que solo el nivel más simple, podría mantener un historial y "saltar hacia atrás y prohibir el control" si el servidor da un mensaje de objeto -locked ... – davidkomer

+0

una resolución de conflicto simple con una manipulación de propiedad similar sería marcar la fecha de interacción del usuario y mantener el último cambio (o si el objeto se elimina simplemente mantenerlo eliminado) – dain

0

Pregunta realmente interesante! El estado de la pizarra se almacena en el servidor (por ejemplo, en DB). Hay 3 acciones posibles en el cliente: startEditing, finishEditing, delete. Justo después de realizar alguna acción, debe enviar un mensaje al servidor para describir una acción.

Si se envía startEditing, primero debe verificar si el objeto que va a editar no tiene bloqueo. Si está desbloqueado, debe poner el candado (el candado debe contener información sobre el usuario que colocó el candado). Luego debe enviar un mensaje a todos los clientes activos para informarles que ese objeto no debe ser editado.

Si finishEditing (este debe contener información sobre los cambios en el objeto) se envía debe cambiar el objeto en DB suelte el candado y envíe el mensaje a todos los clientes activos contando sobre los cambios y bloqueo liberado.

Si se envía delete. Si el objeto no está bloqueado por un cliente diferente al que envió el mensaje, debe eliminar el objeto de la base de datos y enviar un mensaje a todos los clientes activos para eliminar ese objeto de la pizarra

+0

El problema es que cuando se envía startEditing, el "cheque" requiere un servidor de verificación, que introduce el retraso – davidkomer

+0

Si el primer cliente envía 'startEditing' al mismo tiempo que el segundo, algunos de los clientes serán los primeros en poner el candado, y el segundo verá el candado, y no harán nada – Eugeny89

+0

sí, pero de nuevo - El problema es que el cliente debe poder dibujar inmediatamente si tendrá el candado. – davidkomer

0

Puede hacer algo donde usted muestra las interacciones de elementos locales y lo que cualquier otra persona está viendo. Al principio, muestra algo así como que el objeto transparente con el que está interactuando o escribiendo no es definitivo, todo el mundo ve que los objetos/dibujos opacos son finales y lo que uno ve.

Cuando detecta 2 usuarios moviendo un elemento al mismo tiempo, en su propia pantalla ambos son transparentes, en el transcurso de algunas actualizaciones de varios jugadores, el usuario que se ha determinado que tiene control todavía está moviendo el objeto, y usted puede mostrar algún tipo de evento (tal vez un poof genérico) del usuario que estaba moviendo su objeto que ahora se ha determinado que no está bajo su control.

de esta manera obtiene respuesta de dibujo inmediata y un poco de frustración de vez en cuando cuando se determina que no es el que tiene el control de un elemento.

+0

Si lo entiendo bien, es la misma idea que lo que dije antes- "Supongo que solo el nivel más simple, Podría mantener un historial y "saltar hacia atrás y prohibir el control" si el servidor da un mensaje de objeto bloqueado ... " PERO ha agregado una referencia visual en el lado del cliente para que puedan diferenciar entre un objeto que tiene en realidad se mueve frente a un intento de movimiento posiblemente temporal ...? ¿Está bien? ¡Me gusta! – davidkomer

Cuestiones relacionadas