AGS SDKを使用して専用サーバーをAMSに統合する
注釈:本資料はAI技術を用いて翻訳されています。
概要
この記事では、AccelByte Multiplayer Servers (AMS)における専用サーバー(DS)のライフサイクルと、AccelByte Gaming Services (AGS) Game SDKを使用して専用サーバーを統合する方法について説明します。
サーバー側とゲームクライアント側の開発に使用されるSDKは同じSDKです。
前提条件
このガイドを始める前に、以下が必要です:
-
プロジェクト用にAGS Game SDKをインストールして設定していること。AGS Game SDKはUnreal EngineとUnityの両方で利用可能です。SDKのインストール方法については、SDKセットアップガイドを参照してください。
-
Linuxアーキテクチャを使用してビルドされた専用サーバー実行ファイルを準備していること。
注記AMSはLinuxアーキテクチャ用にビルドされた専用サーバーのみをサポートしています。
AMS配下の専用サーバーのライフサイクル
ローカルウォッチドッグは、専用サーバーのライフサイクルを追跡するために状態を使用します。状態は以下の通りです:
- Creating: 専用サーバーがウォッチドッグによって起動され、ゲームセッションを提供するために必要なリソースを読み込んでいます。
- Ready: サーバーはゲームセッションを提供する準備ができています。
- In Session: サーバーはゲームセッションを提供しています。
- Unresponsive: サーバーが予想される時間内にウォッチドッグにハートビートを送信できませんでした。
- Draining: サーバーはセッション中ではなく、drainコマンドが送信されました。
状態の変化は、以下の図で最もよく説明されています:
専用サーバーは、SendReadyMessage() APIを使用してゲームセッションを処理する準備ができたことをウォッチドッグに通知する必要があります。これは、専用サーバーがゲームセッションを提供するために、独自のアセット(ゲームレベルのメッシュなど)を読み込む必要がある場合があるためです。このようなアセットの読み込みに必要な時間は、ゲームによって大きく異なります。SendReadyMessage() APIは、専用サーバーがこれを行う時間を持ち、ゲームセッションを提供する準備ができたことをウォッチドッグに通知できるようにするために使用されます。その後、ウォッチドッグは専用サーバーの状態をCreatingからReadyに変更します。
SDK APIは、ローカルウォッチドッグやAMSシミュレーターへの接続に失敗した場合でも、専用サーバーが独自に実行されることをブロックしません。これにより、AMS要件とは独立して、ローカルで専用サーバーの作業を続けることができます。
AMSとの統合のテストを開始する準備ができたら、AMSシミュレーターを使用してローカルでテストできます。これは、専用サーバーをAMSにアップロードするよりも、AMS統合コードをテストするはるかに高速な方法です。詳細については、AMSシミュレーターの実行セクションを参照してください。
正しいポートのリスニング
AMSは各VM上で複数の専用サーバーを実行します。ポートの競合を避けるために、専用サーバーにはローカルウォッチドッグによって決定された任意のポート番号が割り当てられます。
専用サーバーが起動すると、これらのポート番号はコマンドライン引数の形式で受け取られます。ポート番号を指定するために使用される正確なフラグは、フリート設定の一部であるコマンドラインテンプレートを使用して定義します。
コマンドライン引数の設定の詳細については、専用サーバーコマンドの構築を参照してください。
専用サーバーをAMSに統合する
専用サーバーをAMSに統合するには、以下の手順に従います:
サーバー設定をセットアップする
- Unreal OSS
- Unity
DefaultEngine.iniファイルに以下の設定を追加します。
[OnlineSubsystemAccelByte]
bManualRegisterServer=True
[/Script/AccelByteUe4Sdk.AccelByteSettings]
bServerUseAMS=True
AB Unreal SDKとAB Unreal OSSの混在使用は完全にサポートされておらず、ほとんどの場合機能しません。AB SDKのみを使用するよりも合理化されているため、AB OSSのみを使用して統合することをお勧めします。
専用サーバーをAMSに登録するには、SDKはUnity起動時に専用サーバーID(DS ID)を必要とします。DS IDは--dsidパラメータを使用してコマンドラインで渡されます。AMSで実行する場合、DS IDはds_<uuid>の形式になります。
- Editor
- Linux Server
プロジェクトを開始する前に、Unity Hubからプロジェクトの引数を設定します。例:
-dsId ds_65cb53ac-d2bf-11ef-a6d6-00155d7b207c
サーバーバイナリを実行する前に、DS IDをコマンドライン引数として設定します。
[YourBinaryName].x86_64 -dsId ds_65cb53ac-d2bf-11ef-a6d6-00155d7b207c
マッチメイキングにAGSを使用していて、各ゲームクライアントに最適なレイテンシを持つリージョンのサーバーにマッチングしたい場合は、メニューツールバーのAccelByte > Edit Client SettingsでSDKエディタを開き、Service Url Configs > Use AMS QoS Server Urlのチェックボックスを有効にして、Saveをクリックします。
専用サーバーを登録する
専用サーバーがローカルウォッチドッグによって作成されると、「Creating」状態に移行します。「Creating」状態の間、サーバーは初期化を開始し、ゲームセッションを提供するために必要なすべてのアセットを読み込みます。この間、サーバーは作成タイムアウトの対象となり、タイムアウトを超えると自動的にサーバーが削除されます。
サーバーの読み込みが完了し、ゲームセッションを提供する準備ができたら、サーバーは該当するAPIを呼び出してAMSに通知する必要があります:
- Unreal
- Unreal OSS
- Unity
auto ServerApiClient = AccelByteOnlineSubsystemPtr->GetServerApiClient();
ServerApiClient->ServerAMS.SendReadyMessage();
const FOnRegisterServerComplete OnServerReady = FOnRegisterServerComplete::CreateUObject(this, &YourClass::OnServerReady);
SessionInterface->SendServerReady(TEXT(""), OnServerReady);
// `sessionName`パラメータ(SendServerReady()の最初の引数)は、AMSでは使用されません。その値としてTEXT("")を渡すだけで構いません。
- Editor
- Linux Server
Unity Editorでは、ゲームはSDKがAMSに接続されるのを待つ必要があります。
void SignalReadyForGameSession()
{
ams = AccelByteSDK.GetServerRegistry().GetAMS();
if (ams == null)
{
return;
}
if (ams.IsConnected)
{
ams.SendReadyMessage();
}
else
{
Action signalReady = null;
signalReady = () =>
{
ams.SendReadyMessage();
ams.OnOpen -= signalReady;
};
ams.OnOpen += SignalReady;
}
}
AccelByteSDK.GetServerRegistry().GetAMS().SendReadyMessage();
SendReadyMessage()を呼び出す前に、DSがゲームセッションを提供する準備をするために必要なすべてのことを完了していることを確認してください。ゲームがAGSを使用している場合、これにはサーバーログインの完了が含まれます。DSはログインが完了するまでAGSと対話する準備ができていないためです。
drainシグナルのリスニング
drainシグナルは、専用サーバーが実行されているVMが削除される予定であることを通知します。専用サーバーがゲームセッションを提供していない限り、Draining状態に設定され、drain idle timeoutの対象となります。drain idle timeoutに達すると、ウォッチドッグは自動的に専用サーバーを終了します。In Session状態の専用サーバーは、drainシグナルを受信した後もセッションタイムアウトの対象となります。セッションタイムアウトに達すると、ウォッチドッグは自動的に専用サーバーを終了します。DSがdrainシグナルを受信したら、必要不可欠な作業(通常通りアクティブなゲームセッションを終了することを含む場合があります)を完了してから終了する必要があります。ゲームに異なる動作をする独自の理由がない限り、drainシグナルを受信したDSの通常の予想される動作は次のとおりです:
- DSがアクティブなゲームセッションを提供している場合、通常通りセッションを終了してから終了する
- DSがセッションを提供していない場合(例:「Ready」状態)、できるだけ早くクリーンに終了する
専用サーバーがdrainシグナルを受信する理由はいくつかあります:
- フリートが非アクティブ化された。
- 専用サーバーの需要が減少したため、フリートがスケールインしている。
- 専用サーバーをホストしているノードがメンテナンスのために停止する必要がある。
drainシグナルをリスニングするハンドラーを登録するには、以下を使用します:
- Unreal
- Unreal OSS
- Unity
// まだ作成していない場合は、このインスタンスを一度作成してください。
// インスタンスが以前に作成されている場合は、既存のものを使用してください。
auto AccelByteInstance = IAccelByteUe4SdkModuleInterface::Get().CreateAccelByteInstance();
if (!AccelByteInstance.IsValid()) { return false; }
auto ServerApiClient = AccelByteInstance->GetServerApiClient();
if (!ServerApiClient.IsValid()) { return false; }
ServerApiClient->ServerOauth2.LoginWithClientCredentials(LoginHandler, ErrorHandler);
...
ServerApiClient->ServerDSM.RegisterLocalServerToDSM(GAME_PORT, GAME_SESSION_NAME.ToString(), RegisterHandler, ErrorHandler);
...
// リスナー
auto AmsDrainDelegate = ServerApiClient->ServerAMS.AddOnAMSDrainReceivedMulticastDelegate(AccelByte::GameServerApi::ServerAMS::FOnAMSDrainReceived::CreateLambda([&]() {
bDrainReceived = true;
}));
ServerApiClient->ServerAMS.SendReadyMessage();
//AmsDrainDelegateはリセットに使用できます
AmsDrainDelegate.Reset();
return bDrainReceived;
FOnAMSDrainReceivedDelegate OnAMSDrainReceivedDelegate = FOnAMSDrainReceivedDelegate::CreateUObject(this, &ClassName::OnAMSDrain);
OnAMSDrainReceivedHandle = SessionInterface->AddOnAMSDrainReceivedDelegate_Handle(OnAMSDrainReceivedDelegate);
AccelByteSDK.GetServerRegistry().GetAMS().OnDrainReceived += () =>
{
// アクティブなゲームセッションがない限り、アプリケーションは終了する必要があります
if (!IsSessionActive)
{
ams.Disconnect();
#if UNITY_EDITOR
UnityEditor.EditorApplication.ExitPlaymode();
#else
Application.Quit();
#endif
}
};
完全なコード例については、AGSセッションを使用した完全なコード例を参照してください。
専用サーバーの統合コードと設定が完了したので、AMSシミュレーターを使用してテストする準備ができました。
AMSシミュレーターの実行
AMSシミュレーターは、ウォッチドッグが専用サーバーとどのように対話するかをエミュレートします。これは、専用サーバービルドをアップロードする前に、専用サーバーがAMS環境で動作することを確信できるように、ウォッチドッグとの専用サーバーの対話を検証するための優れたツールです。AMSシミュレーターは、Admin PortalのDownload Resourceページからダウンロードできます。詳細については、Admin PortalからAMS CLIツールをダウンロードするを参照してください。
このセクションは、AMSシミュレーターをスタンドアロンモードで実行する方法について説明しています。スタンドアロンモードでは、ローカルDSはマッチメイキング用のAMSクラウド環境に登録されません。このモードでは、AMSシミュレーターはクラウド環境に接続しません。スタンドアロンモードは、サーバーのAMS統合をテストするのに十分です。マッチメイキングでエンドツーエンドでテストするためにローカルサーバーを(本番)環境に登録する場合は、ローカル専用サーバーをAMSに登録するを参照してください。
AMSシミュレーターを実行するには、次のコマンドを使用します:
> amssim run
config.jsonファイルの生成
runコマンドを初めて呼び出すと、config.jsonファイルが自動的に生成されます。config.jsonはamssim実行ファイルを実行するディレクトリに配置され、専用サーバーを実行するために必要な設定が含まれています。専用サーバーを希望どおりに実行するために、これらの値を自由に変更してください。
config.jsonファイルの例を以下に示します:
{
"WatchdogPort": 5555,
"AGSEnvironmentURL": "",
"AGSNamespace": "",
"IAM": {
"ClientID": "",
"ClientSecret": ""
},
"LocalDSHost": "",
"LocalDSPort": 0,
"ClaimKeys": [],
"ServerName": "my-computer-name"
}
AGSEnvironmentURLを空のままにすると、AMSシミュレーターはスタンドアロンモードで実行されます(この例ではこれが望ましい動作です)。
または、次のコマンドを使用して、デフォルト値でconfig.jsonを生成または置換できます。
> amssim generate-config
セッションの生成
amssimを起動するたびに、一意のamssimセッションが作成されます。infoコマンドを使用してセッション情報を確認できます:
amssim> info
AMS simulator url ws://0.0.0.0:5555/watchdog
AMS simulator session id: 01hcnefg15exp386j9rx901saa.
AMS simulator session log path: session\01hcnefg15exp386j9rx901saa.log
no connected dedicated server
専用サーバーの起動
専用サーバーをAccelByte SDKと統合したら、必要な引数を設定した後、IDEから直接専用サーバーを起動できます。AMSシミュレーターの出力に表示されるコマンドラインの例のように、有効なIDを持つ-dsid引数を専用サーバーに提供します(ただし、ds_<uuid>形式に従っている限り、任意のDS IDが有効です)。また、専用サーバーがリスニングするデフォルトポートを上書きするために-port引数を提供します。config.jsonでWatchdogPortを変更していない場合、AccelByte SDKは自動的にws://localhost:5555/watchdogでAMS SIMインスタンスに接続します。それ以外の場合は、Unrealの場合は-watchdog_urlコマンドライン引数を使用して、Unityの場合は-watchdogUrlを使用して、専用サーバーが正しいポートでAMSシミュレーターに接続していることを確認してください。後でライブフリートで専用サーバーを実行する場合、これらの値はフリート設定に従ってウォッチドッグによって提供されます。(引数の置換の詳細については、専用サーバーコマンドの構築を参照してください。)
接続が成功すると、専用サーバーがReady APIを呼び出したかどうかに応じて、ds状態がCreatingまたはReadyであることがわかります。
AMSで実行する場合、Creating状態のサーバーは作成タイムアウトの対象となり、そのタイムアウトが切れる前に準備ができていることを通知しない場合、ウォッチドッグによって終了されます。amssimはDSプロセスを起動しないため、DSプロセスのライフタイムを管理したり、タイムアウトを強制したりしません。
専用サーバーの状態を確認したい場合は、いつでもこのstatusコマンドを使用します:
amssim> ds status
Ready APIを呼び出さずに専用サーバーをReady状態に設定する
Readyコマンドを使用すると、専用サーバーの状態を他の状態からReadyに設定できます。 これはスタンドアロンモードでは特に有用または興味深いものではありませんが、Local DS機能を使用する場合、DSプロセスを再起動せずに同じDSを繰り返しクレームするために使用できます。
専用サーバーをReady状態に設定するには、次のコマンドを使用します:
amssim> ds ready
サーバーにdrainシグナルを送信する
drainシグナルは、専用サーバーに、アクティブなゲームセッションを中断することなく安全に終了できるときに終了する必要があることを通知します。AMSで実行する場合、In Sessionではなく、drainシグナルを受信したサーバーは、drain idle timeoutの対象となります。
drainシグナルが専用サーバーに送信されると、シグナルはOnDrainReceived()ハンドラーをトリガーします。専用サーバーは、ハンドラーをオーバーライドして、drainシグナルを処理するコードパスを実行できます。
専用サーバーは、セッション中でなくなり、必要な作業を完了したらすぐにクリーンに終了することで、drainシグナルに応答する必要があります。
専用サーバーにdrainシグナルを送信するには、次のコマンドを使用します:
amssim> ds drain
AGSセッションを使用した完全なコード例
- Unity
using AccelByte.Core;
using AccelByte.Models;
using AccelByte.Server;
using System.Collections;
using UnityEngine;
public class AmsDsConnection : MonoBehaviour
{
bool isAmsReady = false;
DedicatedServer ds;
ServerDSHub dsHub;
ServerAMS ams;
IEnumerator Start()
{
#if !UNITY_EDITOR && !(UNITY_STANDALONE_LINUX && UNITY_SERVER)
// この機能はLinux ServerとUnity Editorでのみ利用可能です。
yield break;
#endif
// 専用サーバーがログインして準備ができていることを確認します。
ds = AccelByteSDK.GetServerRegistry().GetApi().GetDedicatedServer();
Result loginResult = null;
ds.LoginWithClientCredentials(result =>
{
if (result.IsError)
{
// LoginWithClientCredentialsが失敗した場合の処理を行います。
Debug.Log($"Error LoginWithClientCredentials, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}
loginResult = result;
// 専用サーバーが正常にログインしたときの追加ロジック。
});
yield return new WaitUntil(() => loginResult != null);
// AMS(サーバービルドでない場合)に接続し、AMSを準備完了として設定します。
ams = AccelByteSDK.GetServerRegistry().GetAMS();
if (ams == null)
{
Debug.LogError("Failed to connect to AMS, please see SDK warning log");
yield break;
}
#if UNITY_STANDALONE_LINUX && UNITY_SERVER
ams.SendReadyMessage();
isAmsReady = true;
#else
// このコードは意図的にエディター専用です。
ams.OnOpen += OnAmsConnected;
#endif
yield return new WaitUntil(() => isAmsReady);
string myServerId = AccelByteSDK.GetServerRegistry().Config.DsId;
// DS Hubに接続し、そのイベントにロジックを設定します。
dsHub = AccelByteSDK.GetServerRegistry().GetApi().GetDsHub();
dsHub.Connect(myServerId);
dsHub.OnConnected += OnDsHubConnected;
dsHub.OnDisconnected += OnDsHubDisconnected;
dsHub.MatchmakingV2ServerClaimed += OnDsHubServerClaimed;
// DS Hubには、カスタムゲームロジック用にリスニングできる多くのイベントがあります。
}
void OnAmsConnected()
{
Debug.Log("AMS connected");
ams.SendReadyMessage();
isAmsReady = true;
ams.OnOpen -= OnAmsConnected;
}
void OnDsHubConnected()
{
Debug.Log("Ds Hub connected");
// DS Hubが正常に接続したときのロジック。
}
void OnDsHubDisconnected(WsCloseCode closeCode)
{
Debug.Log("Ds Hub disconnected");
// DS Hubが切断されたときのロジック。
}
void OnDsHubServerClaimed(Result<ServerClaimedNotification> claimedNotificationResult)
{
ServerClaimedNotification claimedNotification = claimedNotificationResult.Value;
// このインスタンスがゲームセッション用にクレームされたときのロジック
}
}
次のステップ
専用サーバーの統合が完了し、AMSシミュレーターを使用して検証したので、AMS CLIを使用して専用サーバービルドをアップロードする準備ができました。
また、専用サーバービルドをアップロードしてAMSフリートで専用サーバーを展開する前に、統合とクレームフローをテストするために、ローカル専用サーバーをAMSに登録することもできます。