アプリ エンジンをバックエンドとして iOS レーシング ゲームを作成しています。しかし、6月下旬に奇妙なことが起こりました(休暇から戻ったばかりなので、今投稿しています)。
クライアントはスコアを投稿し、サーバーからハイスコアのリストをフェッチし、すべてが完璧に機能しているように見えました (1 か月間テストしましたが、問題はなく、コードは put/get に過ぎず、非常にシンプルです)。しかし、6 月下旬の数時間、古いデータがクライアントに返されました。それはしばらくの間起こりましたが、その後データは自動的に修正されました。
しかし、スコアの送信時に、サーバーがプレーヤーごとに 1 つのハイスコアしか持っていないことを確認するため、これでも問題が発生しましたが、このアプリ エンジンのバグ (?) により、サーバーは一部のプレーヤーに対して複数のスコアを持っていました。
プレーヤー A がスコアを送信し、プレーヤー B がスコアを送信し、データがプレーヤー A しか存在しなかったときに戻され、プレーヤー B が新しいスコアを送信し (サーバーがプレーヤー B を認識しないため保存される)、サーバーがデータの問題を修正し、次に、プレーヤー B を選択する必要があります。
アプリ エンジンのバックエンドに依存できるようにするには、どうすればよいでしょうか。これは契約を破る可能性があります。
より具体的には(コメントで要求されたとおり)
私たちがやっていることを少し単純化していました。でも基本的には同じです。つまり、ハイスコアだけでなく、プレイヤーのゴースト データも保存しています。コードは次のとおりです (ただし、現在は関係のない余分なフィールドがいくつか削除されています)。
モデルは次のとおりです (重要ではないフィールドがいくつか削除されています)。
class Highscore(db.Model):
player = db.StringProperty()
track = db.IntegerProperty()
track_time = db.FloatProperty()
ghost_data = blobstore.BlobReferenceProperty()
そして、保存するために、最初に次のことを行います。
class GhostPrepareHandler(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps({ 'add_highscore_url' : blobstore.create_upload_url('/api/highscore') }))
その後
class HighscoreUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
# Check any previous highscore
track = self.request.get('track')
player = self.request.get('player')
hs = Highscore.all().filter('track =', track).filter('player =', player).get()
# Check if a previous ghost exists with a worse time, if so remove it,
# else if previous time is better, do not store this highscore
if hs is not None:
if hs.track_time < float( self.request.get('track_time') ):
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps({ 'success' : True }))
return
hs.delete()
# Store highscore
hs = Highscore()
hs.player = self.request.get('player')
hs.track = int( self.request.get('track') )
hs.track_time = float( self.request.get('track_time') )
upload = self.get_uploads()[0]
hs.ghost_data = upload.key()
# Store
hs.put()
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps({ 'success' : True }))
そして、読み取り部分を取得しました
def get(self):
player = self.request.get('player')
track = self.request.get('track')
highscores = HighScore.all().filter('track =', track).order('track_time').fetch(limit=4)
highscores_json = []
hs_count = 0
for hs in highscores:
# Filter out player or last ghost
if hs.player == player or hs_count > 2:
continue
hs_obj = {
'player' : hs.player,
'track_time' : hs.track_time,
'ghost_data_url' : 'http://' + host + '/api/highscore/download?ghost_key=' + str( hs.ghost_data.key() )
}
highscores_json.append( hs_obj )
hs_count += 1
self.response.headers['Content-Type'] = 'application/json'
self.response.out.write(json.dumps( highscores_json ))
そして、それは正常に機能していましたが、何らかの理由で、数時間古いデータ (数日前のデータなど) を返しました。