Estoy tratando de construir un juego que use WebSockets. La detección de colisiones y el estado del juego se manejan en el servidor, que ejecuta un bucle de juego aproximadamente cada 16 ms. En cada iteración, envía un mensaje con el estado actualizado a todos los jugadores, que actualizan la copia local y renderizan el juego.
Aproximadamente la mitad de los mensajes llegan bien, pero a veces habrá un lote en el que cientos de ms de tiempo de juego llegan al instante.
Creé un caso de prueba mínimo, que envía la marca de tiempo actual cada 16 ms. En el cliente, puede verlo almacenar mensajes cada dos segundos:
He perfilado la aplicación, y durante la duración de ese gif solo hubo un cuadro perdido, y por lo demás mantuvo 60 fps constantes.
Supongo que GC podría ser la causa de uno de los retrasos, pero en cuanto a los demás y resolver esto, estoy bastante atascado.
La aplicación en sí es Vue, sin embargo, la parte del juego se implementa en JS + Canvas simple.
¿Tu bucle de juego está usando Window.requestAnimationFrame()? Intentaría ejecutar el código websocket por separado, como en un temporizador.
También puede probar otros valores para la actualización de websocket como 36ms, 60ms, 120ms y ver si este problema sigue activo. Tal vez hay demasiadas solicitudes y algo de almacenamiento en caché en el navegador o en el lado del servidor.
No puedo reproducir su problema, debe asegurarse de que esto se deba a la GC. (Si este es el caso, puede intentar eliminar las llamadas pesadas de GC (intente reutilizar objetos/matrices). O tal vez pueda usar su código websocket en un trabajador web de alguna manera, pero si el GC se ejecuta, el subproceso principal se bloquea para que pueda ponga la lógica en el trabajador web también, pero esto es solo una especulación descabellada, de todos modos puede probar la comunicación en un trabajador web sin lógica de juego, solo valores de marcas de tiempo).