問題
Firebase Realtime Database (Unity 用) を使用してターン ベースのゲームのサーバー側を管理していますが、マッチメイキングに問題があります... ダウンロードの使用率が高いです。
すべてのオンライン ゲームには、2 人以上のプレイヤーがゲームに参加することを避けるための 2 つの基本状態があります:作成済みと参加済み
- Created : プレイヤーがゲームに参加しようとしましたが、見つからない場合は新しいゲームが作成されます
- Joined : プレーヤーがゲームに参加しようとして、状態が Created から Joined に変わった場合
RunTransaction
2 人以上のプレイヤーがゲームに参加できないようにするために使用していますが、ローカル キャッシュが原因でデータベースから最新のデータがフェッチされていないことを確認しました。子ノードを追加keepSynced
するmatches-{lang}
と常に最新のデータが保持されますが、当然、ダウンロードの使用率が高い。
private DatabaseReference DatabaseReference()
{
return FirebaseDatabase.DefaultInstance.RootReference.Child(MatchesLocation(LanguageManager.Manager.GetPlayerLanguageCode()));
}
private DatabaseReference DatabaseReferenceLangMatch(Language language)
{
return FirebaseDatabase.DefaultInstance.RootReference.Child(MatchesLocation(LanguageManager.Manager.GetLanguageCode(language)));
}
public void ManageKeepSyncedMatches(Language lang)
{
DatabaseReferenceLangMatch(Language.English).KeepSynced(lang == Language.English);
}
public void JoinMatchTransaction(GameMatchOnline gameMatchOnline, UnityAction<string, bool> callback)
{
JoinTransactionAbort joinResult = JoinTransactionAbort.None;
DatabaseReference matchesListRef = DatabaseReference();
Dictionary<string, object> joinerDict = gameMatchOnline.ToJoinDictionary();
matchesListRef.Child(gameMatchOnline.matchId).RunTransaction(matchData =>
{
Dictionary<string, object> matchDict = matchData.Value as Dictionary<string, object>;
if (matchDict == null)
{
joinResult = JoinTransactionAbort.Null;
return TransactionResult.Success(null);
}
if (!matchDict.ContainsKey("state"))
{
joinResult = JoinTransactionAbort.Error;
return TransactionResult.Abort();
}
GameMatchOnline.State state = (GameMatchOnline.State)System.Convert.ToInt32(matchDict["state"]);
if (state != GameMatchOnline.State.Created)
{
joinResult = JoinTransactionAbort.Error;
return TransactionResult.Abort();
}
joinResult = JoinTransactionAbort.None;
matchDict.Add("joinerInfo", joinerDict["joinerInfo"]);
matchDict["state"] = joinerDict["state"];
matchData.Value = matchDict;
return TransactionResult.Success(matchData);
}).ContinueWith(task =>
{
// Fail
if (task.IsFaulted || task.IsCanceled)
{
UnityThread.executeInUpdate(() =>
{
if (joinResult == JoinTransactionAbort.Error)
{
callback(null, false);
}
});
}
// Can Join match
else if (task.IsCompleted)
{
UnityThread.executeInUpdate(() =>
{
if (joinResult == JoinTransactionAbort.None)
{
AddListenerResultsValueChanged(gameMatchOnline.matchId, gameMatchOnline.joinerInfo.userId, gameMatchOnline.isPrivate, gameMatchOnline.language);
callback(gameMatchOnline.matchId, true);
}
else
{
callback(null, false);
}
});
}
});
}
質問
- プレイヤーを削除
keepSynced
すると、ローカルにキャッシュされた の情報が保持されますmatches-{lang}
。これを行うことで、ゲームごとに 2 人以下のプレイヤーが存在することを信頼できますか? *トランザクションは、このような問題を回避するためのものです。 - リクエストのローカル キャッシュを回避して、常に更新されたデータを取得する方法はありますか?
- ゲームを別のノードに移動してノードのサイズを縮小することが最善の解決策
matches-{lang}
でしょうか?
ありがとう!