Bugünlerde şirketim için yeni bir MMORPG mobil oyun mimarisi tasarlamaya çalışıyorum. Bu oyun Mafya Savaşları, iMobsterler veya RİSK'e benzer. Temel fikir, rakiplerinizle (çevrimiçi kullanıcılar) savaşacak bir ordu hazırlamaktır.
Daha önce birden çok mobil uygulama üzerinde çalışmış olmama rağmen bu benim için yeni bir şey. Bir çok mücadeleden sonra, üst düzey bir akış şeması yardımıyla gösterilen bir mimari ortaya çıkardım:
İstemci-sunucu modeli ile gitmeye karar verdik. Sunucuda merkezi bir veritabanı olacaktır. Her istemcinin sunucuyla senkronize kalacak kendi yerel veritabanı olacaktır. Bu veritabanı, haritalar, ürünler, envanter vb. Gibi sık sık değişmeyen şeyleri saklamak için bir önbellek görevi görür.
Bu model yerinde olduğunda, aşağıdaki sorunların nasıl çözüleceğinden emin değilim:
- Sunucu ve istemci veritabanlarını senkronize etmenin en iyi yolu nedir?
- Bir olay sunucuya güncellenmeden önce yerel DB'ye kaydedilmeli mi? Uygulama, merkezi DB'deki değişiklikleri kaydetmeden önce herhangi bir nedenle sona ererse ne olur?
- Basit HTTP istekleri senkronizasyon amacına hizmet eder mi?
- Şu anda hangi kullanıcıların oturum açtığını nasıl öğrenebilirim? (Bunun bir yolu, istemcinin etkin olduğunu bildirmek için her x dakikada bir sunucuya istek göndermeye devam etmesini sağlamak olabilir. Aksi takdirde istemciyi devre dışı bırakın).
- İstemci tarafı doğrulamaları yeterli mi? Değilse, sunucu bir şeyi doğrulamazsa bir eylem nasıl geri alınır?
Bunun etkili bir çözüm olup olmadığından ve nasıl ölçekleneceğinden emin değilim. Bu tür uygulamalarda zaten çalışmış olan kişilerin deneyimlerini paylaşıp paylaşamayacaklarını daha iyi bir şey bulmamı gerçekten takdir ediyorum. Şimdiden teşekkürler.
İlave bilgi:
İstemci tarafı marmelat adı verilen C ++ oyun motorunda uygulanmaktadır. Bu, uygulamanızı tüm büyük mobil işletim sistemlerinde çalıştırabileceğiniz bir çapraz platform oyun motorudur. Kesinlikle iplik geçirmeyi başarabiliriz ve bu da benim akış diyagramımda gösterilmiştir. Sunucu için MySQL ve istemci için SQLite kullanmayı planlıyorum.
Bu sıra tabanlı bir oyun değil, bu yüzden diğer oyuncularla çok fazla etkileşim yok. Sunucu çevrimiçi oyuncuların bir listesini sunacak ve savaş düğmesine tıklayarak onlarla savaşabilirsiniz ve bazı animasyonlardan sonra sonuç duyurulacaktır.
Veritabanı senkronizasyonu için iki çözüm var:
- Her kayıt için zaman damgasını saklayın. Ayrıca, yerel DB'nin en son ne zaman güncellendiğini de takip edin. Senkronize ederken, yalnızca daha büyük zaman damgası olan satırları seçin ve yerel DB'ye gönderin. Silinmiş satırlar için isDeleted bayrağını saklayın, böylece her silme işlemi bir güncelleme görevi görür. Ancak, tüm DB isteğini taramak ve güncellenmiş satırları aramak zorunda kalacağımız her senkronizasyon isteği için performans konusunda ciddi şüphelerim var.
- Başka bir teknik, bir kullanıcıya karşı gerçekleştirilen her ekleme veya güncellemenin günlüğünü tutmak olabilir. İstemci uygulaması senkronizasyon istediğinde, bu tabloya gidin ve hangi tablonun hangi satırların güncellendiğini veya eklendiğini öğrenin. Bu satırlar başarıyla istemciye aktarıldıktan sonra bu günlüğü kaldırın. Ama sonra bir kullanıcı başka bir cihaz kullanıyorsa ne olacağını düşünüyorum. Günlükler tablosuna göre, bu kullanıcı için tüm güncellemeler aktarıldı, ancak aslında başka bir cihazda yapıldı. Bu yüzden cihazı da takip etmek zorunda kalabiliriz. Bu tekniği uygulamak daha fazla zaman alır, ancak ilkinin uygulanıp uygulanmadığından emin değildir.