Obecnie próbuję zaprojektować architekturę nowej gry mobilnej MMORPG dla mojej firmy. Ta gra jest podobna do Mafia Wars, iMobsters lub RISK. Podstawowym pomysłem jest przygotowanie armii do walki z przeciwnikami (użytkownicy online).
Chociaż wcześniej pracowałem nad wieloma aplikacjami mobilnymi, ale jest to dla mnie coś nowego. Po wielu zmaganiach opracowałem architekturę ilustrowaną za pomocą schematu wysokiego poziomu:
Zdecydowaliśmy się na model klient-serwer. Na serwerze będzie scentralizowana baza danych. Każdy klient będzie miał własną lokalną bazę danych, która pozostanie zsynchronizowana z serwerem. Ta baza danych działa jako pamięć podręczna do przechowywania rzeczy, które nie zmieniają się często, np. Mapy, produkty, zapasy itp.
Po wdrożeniu tego modelu nie jestem pewien, jak rozwiązać następujące problemy:
- Jaki byłby najlepszy sposób synchronizacji baz danych serwera i klienta?
- Czy zdarzenie powinno zostać zapisane w lokalnej bazie danych przed aktualizacją do serwera? Co jeśli aplikacja z jakiegoś powodu zostanie zakończona przed zapisaniem zmian w scentralizowanej bazie danych?
- Czy proste żądania HTTP będą służyć synchronizacji?
- Jak sprawdzić, którzy użytkownicy są obecnie zalogowani? (Jednym ze sposobów może być wysyłanie przez klienta żądania do serwera co x minut w celu powiadomienia, że jest ono aktywne. W przeciwnym razie należy uznać klienta za nieaktywny).
- Czy wystarczające są weryfikacje po stronie klienta? Jeśli nie, jak cofnąć akcję, jeśli serwer czegoś nie zweryfikuje?
Nie jestem pewien, czy jest to skuteczne rozwiązanie i jak się skaluje. Byłbym bardzo wdzięczny, gdyby ludzie, którzy już pracowali nad takimi aplikacjami, mogli podzielić się swoimi doświadczeniami, które mogą pomóc mi wymyślić coś lepszego. Z góry dziękuję.
Dodatkowe informacje:
Po stronie klienta zaimplementowano silnik gry C ++ o nazwie marmolada. Jest to wieloplatformowy silnik gry, co oznacza, że możesz uruchomić aplikację na wszystkich głównych systemach operacyjnych dla urządzeń mobilnych. Z pewnością możemy osiągnąć gwintowanie, co zostało również zilustrowane na moim schemacie blokowym. Planuję używać MySQL dla serwera i SQLite dla klienta.
To nie jest gra turowa, więc nie ma wiele interakcji z innymi graczami. Serwer dostarczy listę graczy online i możesz z nimi walczyć klikając przycisk bitwy, a po animacji zostanie ogłoszony wynik.
Do synchronizacji baz danych mam na myśli dwa rozwiązania:
- Przechowuj znacznik czasu dla każdego rekordu. Śledź również datę ostatniej aktualizacji lokalnego DB. Podczas synchronizacji wybierz tylko te wiersze, które mają większy znacznik czasu i wyślij do lokalnej bazy danych. Zachowaj flagę isDeleted dla usuniętych wierszy, aby każde usunięcie zachowywało się jak aktualizacja. Ale mam poważne wątpliwości co do wydajności, ponieważ przy każdym żądaniu synchronizacji musielibyśmy przeskanować całą bazę danych i poszukać zaktualizowanych wierszy.
- Inną techniką może być prowadzenie dziennika każdego wstawiania lub aktualizacji, która ma miejsce w stosunku do użytkownika. Gdy aplikacja kliencka prosi o synchronizację, przejdź do tej tabeli i dowiedz się, które wiersze której tabeli zostały zaktualizowane lub wstawione. Po pomyślnym przesłaniu tych wierszy do klienta usuń ten dziennik. Ale potem myślę o tym, co się stanie, jeśli użytkownik użyje innego urządzenia. Zgodnie z tabelą dzienników wszystkie aktualizacje zostały przesłane dla tego użytkownika, ale tak naprawdę zostało to zrobione na innym urządzeniu. Być może będziemy musieli również śledzić urządzenie. Wdrożenie tej techniki jest bardziej czasochłonne, ale nie jestem pewien, czy zostanie ona wykonana jako pierwsza.