ゲームサーバー:接続エラー時のプレイヤー統計更新の処理方法
Last updated on February 4, 2026
注釈:本資料はAI技術を用いて翻訳されています。
サービスメンテナンスは、安定した接続に依存する特定のゲームサーバーアクティビティを中断し、期待通りに動作しなくなる可能性があります。例えば、ゲームサーバーがマッチ結果に基づいてプレイヤー統計を更新するが、接続を失い、接続再試行がタイムアウトに達した場合、統計は更新されません。この問題を防ぐために、開発者は失敗した更新を処理する方法を追加する必要があります。一般的なアプローチの1つは、ゲームレベルでリクエストを再試行するためにタイマーを使用することです。以下は、最大5回の再試行と10秒の再試行遅延でこの再試行システムを実装する方法の例です。
- Unreal Engine OSS
- Unreal Engine SDK
- Unity
...
FOnUpdateMultipleUserStatItemsComplete OnServerUpdateStatsComplete;
int MaxRetryAttempts{5};
int NRetryAttempt{0};
int RetryDelay{10};
FTimerHandle RetryTimerHandle;
...
void UpdatePlayerMMR()
{
...
auto ABSubsystem = IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM);
auto StatsInterface = ABSubsystem->GetStatsInterface();
auto ABStatsInterface = StaticCastSharedPtr<FOnlineStatisticAccelByte>(StatsInterface);
int32 LocalUserNum = 0;
TArray<FOnlineStatsUserUpdatedStats> UpdatedUsersStats;
FOnlineStatsUserUpdatedStats UpdatedUserStats(PlayerUniqueId->AsShared());
UpdatedUserStats.Stats.Add(TTuple<FString, FOnlineStatUpdate>
{
TEXT("MMR"),
FOnlineStatUpdate
{
50,
FOnlineStatUpdate::EOnlineStatModificationType::Set
}
});
OnServerUpdateStatsComplete = FOnUpdateMultipleUserStatItemsComplete::CreateWeakLambda(
this, [this](const FOnlineError& ResultState, const TArray<FAccelByteModelsUpdateUserStatItemsResponse>& Result)
{
if (ResultState.bSucceeded)
{
// 統計の更新が成功したときに何かを実行します。
NRetryAttempt = 0;
}
else
{
// 失敗したリクエストを処理するソリューションを実装します。
if(NRetryAttempt < MaxRetryAttempts)
{
GetWorld()->GetTimerManager().SetTimer(RetryTimerHandle, [this]()
{
UpdatePlayerMMR();
}, RetryDelay, false);
NRetryAttempt++;
}
}
OnServerUpdateStatsComplete.Unbind();
});
ABStatsInterface->UpdateStats(LocalUserNum, UpdatedUsersStats, OnServerUpdateStatsComplete);
...
}
...
int MaxRetryAttempts{5};
int NRetryAttempt{0};
int RetryDelay{10};
FTimerHandle RetryTimerHandle;
...
void UpdatePlayerMMR()
{
...
FAccelByteModelsUpdateUserStatItem UserStatItem;
UserStatItem.Value = 50;
FServerApiClientPtr ServerApiClient = AccelByteOnlineSubsystemPtr->GetServerApiClient();
ServerApiClient->ServerStatistic.UpdateUserStatItemValue(TEXT("<UserId>"), TEXT("MMR"), TEXT(""), UserStatItem,
THandler<FAccelByteModelsUpdateUserStatItemValueResponse>::CreateLambda([this](const FAccelByteModelsUpdateUserStatItemValueResponse& Result)
{
// プレイヤー統計MMRの更新が成功したときに何かを実行します。
NRetryAttempt = 0;
}), FErrorHandler::CreateLambda([this](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Warning, TEXT("Error updating player stat MMR. Code: %d, Message: %s"), ErrorCode, *ErrorMessage);
if(ErrorCode == static_cast<int32>(ErrorCodes::NetworkError))
{
// HTTP再試行タイムアウトを処理するソリューションを実装します。
if(NRetryAttempt < MaxRetryAttempts)
{
GetWorld()->GetTimerManager().SetTimer(RetryTimerHandle, [this]()
{
UpdatePlayerMMR();
}, RetryDelay, false);
NRetryAttempt++;
}
}
})
);
...
}
...
int maxRetryAttempts = 5;
int nRetryAttempt = 0;
int retryDelay = 10;
...
public void UpdatePlayerMMR()
{
...
PublicUpdateUserStatItem publicUpdateUserStatItem = new PublicUpdateUserStatItem
{
value = 50
};
AccelByteSDK.GetClientRegistry().GetApi().GetStatistic().UpdateUserStatItemsValue("MMR", "", publicUpdateUserStatItem, result =>
{
if (!result.IsError)
{
// 合意の受諾が成功したときに何かを実行します。
nRetryAttempt = 0;
}
else
{
// 失敗したリクエストを処理するソリューションを実装します。
Debug.LogWarning($"Unable to login. Code: {result.Error.Code}, Message: {result.Error.Message}");
if(result.Error.Code.Equals(ErrorCode.NetworkError))
{
// HTTP再試行タイムアウトを処理するソリューションを実装します。
StartCoroutine(RetryUpdatePlayerMMR);
}
}
});
...
}
private IEnumerator RetryUpdatePlayerMMR()
{
if(nRetryAttempt < maxRetryAttempts)
{
yield return new WaitForSeconds(retryDelay);
nRetryAttempt++;
UpdatePlayerMMR();
}
else
{
// エラーメッセージのポップアップを表示します!
}
}
リクエストがここにリストされているエラーコードのいずれかに遭遇した場合、システムがリクエストの再試行を開始するときにエラーデリゲートはトリガーされません。エラーデリゲートは、再試行プロセスが終了した後にのみトリガーされます—再試行制限に達した場合(タイムアウト)、または最終的なレスポンスコードがリストされているエラーコードのいずれでもない場合です。