В эти дни я пытаюсь разработать архитектуру новой мобильной игры MMORPG для моей компании. Эта игра похожа на Mafia Wars, iMobsters или RISK. Основная идея состоит в том, чтобы подготовить армию для сражения с вашими противниками (онлайн-пользователями).
Хотя я ранее работал над несколькими мобильными приложениями, но это что-то новое для меня. После долгой борьбы я придумал архитектуру, которая проиллюстрирована с помощью блок-схемы высокого уровня:
Мы решили перейти на клиент-серверную модель. На сервере будет централизованная база данных. Каждый клиент будет иметь свою собственную локальную базу данных, которая будет синхронизирована с сервером. Эта база данных действует как кеш для хранения вещей, которые не меняются часто, например. карты, продукты, инвентарь и т. д.
С этой моделью я не уверен, как решить следующие проблемы:
- Каков наилучший способ синхронизации серверных и клиентских баз данных?
- Должно ли событие сохраняться в локальной БД перед его обновлением на сервере? Что делать, если приложение по какой-то причине завершает работу до сохранения изменений в централизованной БД?
- Будут ли простые HTTP-запросы служить цели синхронизации?
- Как узнать, какие пользователи в данный момент вошли в систему? (Один из способов может заключаться в том, чтобы клиент продолжал отправлять запрос на сервер каждые x минут, чтобы уведомить, что он активен. В противном случае клиент считается неактивным).
- Достаточно ли проверок на стороне клиента? Если нет, как отменить действие, если сервер что-то не проверяет?
Я не уверен, является ли это эффективным решением и как оно будет масштабироваться. Я был бы очень признателен, если бы люди, которые уже работали над такими приложениями, поделились своим опытом, который мог бы помочь мне придумать что-то лучшее. Заранее спасибо.
Дополнительная информация:
Клиентская часть реализована на игровом движке C++ под названием marmalade. Это кроссплатформенный игровой движок, что означает, что вы можете запускать свое приложение на всех основных мобильных ОС. Мы, безусловно, можем добиться многопоточности, что также показано на моей блок-схеме. Я планирую использовать MySQL для сервера и SQLite для клиента.
Это не пошаговая игра, поэтому взаимодействия с другими игроками не так много. Сервер предоставит список онлайн-игроков, и вы можете сразиться с ними, нажав кнопку битвы, и после некоторой анимации будет объявлен результат.
Для синхронизации базы данных у меня есть два решения:
Хранить временную метку для каждой записи. Также следите за тем, когда в последний раз обновлялась локальная БД. При синхронизации выбирайте только те строки, которые имеют большую временную метку и отправляйте в локальную БД. Сохраняйте флаг isDeleted для удаленных строк, чтобы каждое удаление просто вело себя как обновление. Но у меня есть серьезные сомнения по поводу производительности, так как для каждого запроса на синхронизацию нам придется сканировать всю БД и искать обновленные строки.
Другой метод может состоять в том, чтобы вести журнал каждой вставки или обновления, которые происходят в отношении пользователя. Когда клиентское приложение запрашивает синхронизацию, перейдите к этой таблице и узнайте, какие строки какой таблицы были обновлены или вставлены. Как только эти строки будут успешно переданы клиенту, удалите этот журнал. Но затем я думаю о том, что произойдет, если пользователь использует другое устройство. Согласно таблице журналов все обновления были переданы для этого пользователя, но на самом деле это было сделано на другом устройстве. Таким образом, нам, возможно, придется также отслеживать устройство. Реализация этого метода требует больше времени, но не уверен, что он работает лучше первого.