2009-04-21 29 views
7

Estoy trabajando en una aplicación de servidor C# para un motor de juego que estoy escribiendo en ActionScript 3. Estoy usando un modelo de servidor autorizado para evitar hacer trampa y asegurar juego justo. Hasta ahora, todo funciona bien:¿Cómo puedo obtener la latencia entre el servidor y el cliente en C#

Cuando el cliente comienza a moverse, le dice al servidor y comienza a procesar localmente; el servidor, entonces, le dice a todos los demás que el cliente X ha comenzado a moverse, entre los detalles para que también puedan comenzar a renderizar. Cuando el cliente deja de moverse, le dice al servidor, que realiza cálculos basados ​​en el momento en que el cliente comenzó a moverse, y el cliente procesa el retraso y responde a todos, para que puedan actualizar con los valores correctos.

El hecho es que cuando uso la demora de tics predeterminada de 20ms en los cálculos del servidor, cuando el cliente se mueve por una distancia bastante larga, hay una inclinación hacia delante cuando se detiene. Si aumente ligeramente el retraso a 22 ms, en mi red local todo funciona sin problemas, pero en otros lugares, la inclinación todavía está allí. Después de experimentar un poco, noté que el retraso adicional necesario está más o menos ligado a la latencia entre el cliente y el servidor. Incluso lo reduje a una fórmula que funcionaría muy bien: delay = 20 + (latencia/10).

Entonces, ¿cómo procedería para obtener la latencia entre un determinado cliente y el servidor (estoy utilizando conectores asíncronos). El esfuerzo de la CPU no puede ser demasiado, para que el servidor no se ejecute lentamente. Además, ¿esta es realmente la mejor manera, o hay una manera más eficiente/más fácil de hacer esto?

Respuesta

12

Disculpe que esto no responde directamente su pregunta, pero en general no debe confiar demasiado en la medición de la latencia porque puede ser bastante variable . No solo eso, no sabes si el tiempo de ping que mides es incluso simétrico, lo cual es importante. No tiene sentido aplicar 10 ms de corrección de latencia si resulta que el tiempo de ping de 20 ms es de 19 ms de un servidor a otro y de 1 ms de un cliente a otro. Y la latencia en términos de aplicación no es lo mismo que en términos de red: puede hacer ping a una máquina determinada y obtener una respuesta en 20 ms, pero si se está contactando con un servidor en esa máquina que solo procesa la entrada de red 50 veces por segundo, sus respuestas se retrasarán entre 0 y 20 ms adicionales, y esto variará de forma bastante impredecible.

Eso no quiere decir que la medición de la latencia no tenga un lugar en suavizar las predicciones, pero no va a resolver su problema, simplemente límpielo un poco.

En apariencia, el problema aquí parece ser que se le envía información en el primer mensaje que utiliza para extrapolar los datos hasta que se recibe el último mensaje. Si todo lo demás permanece constante, el vector de movimiento dado en el primer mensaje multiplicado por el tiempo entre los mensajes dará al servidor la posición final correcta en la que se encontraba el cliente aproximadamente ahora (latencia/2). Pero si la latencia cambia, el tiempo entre los mensajes aumentará o disminuirá. El cliente puede saber que ha movido 10 unidades, pero el servidor lo simuló moviendo 9 u 11 unidades antes de que le dijeran que lo devolviera a 10 unidades.

La solución general a esto es no asumir que la latencia se mantendrá constante sino enviar actualizaciones de posición periódicas, que permitan al servidor verificar y corregir la posición del cliente. Con solo 2 mensajes como ahora, todos los errores se encuentran y se corrigen después del segundo mensaje. Con más mensajes, el error se extiende a muchos más puntos de muestra, lo que permite una corrección más suave y menos visible.

Sin embargo, nunca puede ser perfecto: todo lo que se necesita es un pico de retraso en el último milisegundo de movimiento y la representación del servidor se rebasará. No se puede evitar eso si se está prediciendo un movimiento futuro basado en eventos pasados, ya que no existe una alternativa real a la elección correcta o tardía o incorrecta pero puntual, ya que la información toma tiempo para viajar. (Culpa a Einstein.)

+0

+1 por "Blame Einstein". –

2

Tiene un comando "ping", donde se envía un mensaje del servidor al cliente, luego el tiempo que tarda en obtener una respuesta. Excepto escenarios de sobrecarga de CPU, debería ser bastante confiable. Para obtener el tiempo de viaje de ida, simplemente divida el tiempo por 2.

+1

Dependiendo de la aplicación, casi todos los mensajes pueden llevar el subpaquete ping sin superar el límite de 1518 o más. De esta forma, puedes adaptarte automáticamente al clima cambiante de la red. –

4

Puede utilizar la clase Ping ya disponible. Debería preferirse a escribir su propio mi humilde opinión.

4

Una cosa a tener en cuenta al utilizar ICMPpings basadas es que los equipos de red a menudo dará el tráfico ICMP menor prioridad que paquetes normales, especialmente cuando los paquetes cruzan límites de la red, tales como enlaces WAN. Esto puede hacer que los pings se pierdan o que muestren una latencia más alta de lo que el tráfico realmente está experimentando y se presta a ser un indicador de problemas en lugar de una herramienta de medición.

El creciente uso de Quality of Service (QoS) en redes sólo agrava este y, como consecuencia, aunque de ping sigue siendo una herramienta útil, tiene que entenderse que puede que no sea un fiel reflejo de la latencia de la red para los no-ICMP basado en real tráfico.

Hay una buena publicación en el blog de Itrinegy How do you measure Latency (RTT) in a network these days? acerca de esto.

Cuestiones relacionadas