Estoy usando Node.js y Redis. Estoy tratando de encontrar una forma confiable de atrapar jugadores automáticamente. Hay un servidor coincidente y luego se configuran varios servidores de juegos.
Lo siguiente es lo que necesito que suceda:
- El jugador envía una solicitud de ingreso con el tipo de juego (pequeño / mediano, etc.)
- El servidor coincidente agrega al jugador al tipo de juego actual que está esperando a los jugadores
- El servidor del juego envía al jugador la ID del juego
Actualmente lo he implementado de la siguiente manera:
- El servidor coincidente escucha el juego: cola: pequeña usando BRPOP
- Comprueba si el juego: cola: pequeño: id = id existe
- Comprueba si el juego: id: la longitud de los usuarios es <= 6 (jugadores máximos)
- Agrega jugador al juego: id: lista de usuarios si es
- Si la duración del juego ahora es 6, elimina game: queue: small: id
Si el servidor coincidente encuentra game: queue: small: id falta, hace lo siguiente:
- Juego INCR: nextGameId
- Establece game: queue: small: id a la ID generada previamente
- Agrega el ID del juego al juego: cola: esperando
Los servidores del juego esperan usar BRPOP para nuevos juegos. Cuando obtienen uno, esperan hasta que el juego tenga un mínimo de 2 usuarios y luego inician un temporizador. Si no se llenan en ese tiempo, comienzan con los usuarios que tienen y luego eliminan game: queue: small: id (lo que obliga al matchmaker a solicitar un nuevo juego).
Mientras mi método funciona, no estoy convencido de que funcione bien en la producción y parece muy complicado. Puedo ver el potencial de los siguientes problemas:
- El servidor del juego se bloquea después de aceptar la ID del juego de la lista de espera, lo que hace que los usuarios se agreguen al juego: id: usuarios pero no sucede nada con ellos (el bloqueo en sí no es un problema, pero los usuarios que continúan agregándose a esa cola de juegos es )
- Si un usuario se desconecta y el juego no ha comenzado, el servidor del juego eliminará al usuario del juego: id: lista de usuarios. Mientras está en el proceso de hacer eso, el servidor de emparejamiento podría estar agregando un usuario a la lista y pensar que el juego está lleno, eliminándolo de la cola.
Mis pensamientos iniciales fueron cambiar a una sola cola de usuarios que esperaban un tipo de juego. Sin embargo, esto presenta más problemas:
- Si el servidor al que se conectan los usuarios se bloquea, no eliminará al usuario de la cola y, por lo tanto, dejará que ese usuario ingrese a un juego cuando no exista. Podría usar conjuntos ordenados para almacenar el tiempo de la solicitud y hacer que el cliente realice una encuesta hasta que se devuelva una ID del juego, pero esto significaría que no tengo idea de cuánto tiempo ha esperado ese cliente y, por lo tanto, no sé si iniciar el juego con menos usuarios
- Sin poner a los usuarios en un juego, no tienen la capacidad de ver a qué usuarios se han unido, ni tienen la posibilidad de chatear con los usuarios que están esperando (ya que eso requiere una identificación del juego).
Ninguna de las formas en que he configurado esto se siente bien, así que esperaba que alguien pudiera ofrecer algunas sugerencias mejores. Realmente necesito mantener separados los servidores del juego y los servidores de emparejamiento para poder crecer según sea necesario.
fuente
Respuestas:
Su primer y principal error es usar una base de datos para una cola en vivo, es mucho mejor almacenar los datos en la memoria del proceso en el proceso de emparejamiento. Deje que los procesos se comuniquen entre sí directamente. Entonces también es bastante forzado para ti que es responsabilidad exclusiva del servidor de emparejamiento eliminar a los jugadores de la cola cuando se ponen en un juego, como debería ser.
En términos más generales sobre emparejamiento, retrase las decisiones de qué partidos exactos hacer hasta el punto donde comienza el juego, si tiene 3 jugadores que encajan en un juego de 4 jugadores, no decida que tienen que jugar ese tipo de juego antes de que haya también un cuarto jugador, podría tomar mucho tiempo para que llegue ese jugador, y algunos de ellos podrían dejar de esperar mientras tanto. Una implementación decente para esto es tener una cola para cada tipo de juego y poner a cada jugador en todas las colas que coincidan con su solicitud, luego, cuando una cola esté llena, comience el juego y elimine a los jugadores involucrados de todas sus colas.
fuente