En estos días estoy tratando de diseñar la arquitectura de un nuevo juego móvil MMORPG para mi empresa. Este juego es similar a Mafia Wars, iMobsters o RISK. La idea básica es preparar un ejército para luchar contra tus oponentes (usuarios en línea).
Aunque anteriormente he trabajado en múltiples aplicaciones móviles, esto es algo nuevo para mí. Después de mucha lucha, se me ocurrió una arquitectura que se ilustra con la ayuda de un diagrama de flujo de alto nivel:
Hemos decidido ir con el modelo cliente-servidor. Habrá una base de datos centralizada en el servidor. Cada cliente tendrá su propia base de datos local que permanecerá sincronizada con el servidor. Esta base de datos actúa como un caché para almacenar cosas que no cambian con frecuencia, por ejemplo, mapas, productos, inventario, etc.
Con este modelo, no estoy seguro de cómo abordar los siguientes problemas:
- ¿Cuál sería la mejor manera de sincronizar las bases de datos de servidores y clientes?
- ¿Se debe guardar un evento en la base de datos local antes de actualizarlo al servidor? ¿Qué sucede si la aplicación finaliza por algún motivo antes de guardar los cambios en la base de datos centralizada?
- ¿Las solicitudes HTTP simples servirán para la sincronización?
- ¿Cómo saber qué usuarios están actualmente conectados? (Una forma podría ser que el cliente continúe enviando una solicitud al servidor después de cada x minutos para notificar que está activa. De lo contrario, considere que un cliente está inactivo).
- ¿Son suficientes las validaciones del lado del cliente? Si no, ¿cómo revertir una acción si el servidor no valida algo?
No estoy seguro de si esta es una solución eficiente y cómo escalará. Realmente agradecería que las personas que ya han trabajado en tales aplicaciones puedan compartir sus experiencias, lo que podría ayudarme a encontrar algo mejor. Gracias por adelantado.
Información adicional:
El lado del cliente está implementado en un motor de juego C ++ llamado mermelada. Este es un motor de juegos multiplataforma, lo que significa que puede ejecutar su aplicación en todos los principales sistemas operativos móviles. Ciertamente podemos lograr el enhebrado y eso también se ilustra en mi diagrama de flujo. Estoy planeando usar MySQL para el servidor y SQLite para el cliente.
Este no es un juego por turnos, por lo que no hay mucha interacción con otros jugadores. El servidor proporcionará una lista de jugadores en línea y puedes luchar contra ellos haciendo clic en el botón de batalla y después de un poco de animación, se anunciará el resultado.
Para la sincronización de bases de datos, tengo dos soluciones en mente:
- Guarde la marca de tiempo para cada registro. También realice un seguimiento de cuándo se actualizó por última vez la base de datos local. Al sincronizar, solo seleccione aquellas filas que tengan una marca de tiempo mayor y envíelas a la base de datos local. Mantenga un indicador isDeleted para las filas eliminadas para que cada eliminación simplemente se comporte como una actualización. Pero tengo serias dudas sobre el rendimiento ya que para cada solicitud de sincronización tendríamos que escanear la base de datos completa y buscar filas actualizadas.
- Otra técnica podría ser mantener un registro de cada inserción o actualización que tenga lugar contra un usuario. Cuando la aplicación cliente solicite sincronización, vaya a esta tabla y descubra qué filas de esa tabla se han actualizado o insertado. Una vez que estas filas se transfieren correctamente al cliente, elimine este registro. Pero luego pienso en lo que sucede si un usuario usa otro dispositivo. Según la tabla de registros, todas las actualizaciones se han transferido para ese usuario, pero en realidad eso se hizo en otro dispositivo. Por lo tanto, podríamos tener que hacer un seguimiento del dispositivo también. La implementación de esta técnica lleva más tiempo, pero no estoy seguro de si supera la primera.