qos
note
#
概要Multiplay には、クライアントが利用可能なリージョンのうち、オンラインセッションで最高の通信品質が期待できるリージョンを動的に判断するのに役立つ、サービス品質(QoS)プロトコルが用意されています。このドキュメントでは、QoS プロトコルのコンポーネント、各コンポーネントの使用方法、クライアントのカスタム実装を記述するときに考慮するベストプラクティスについて、大まかに説明します。
QoS プロトコルは、Discovery と QoS の 2 つの主要なコンポーネントで構成されています。
- Discovery を使用すると、クライアントが実行時に、現在どのリージョンで通信品質をテストできるかを判断できます。
- QoS を使用すると、クライアントが利用可能な各リージョンの通信品質をテストできます。
このドキュメントでは、Multiplay の用語や概念(フリート、位置、リージョンなど)に精通していることを前提としています。詳細については、https://docs.multiplay.com/ を参照してください。
#
Discovery サービスDiscovery サービスを使用すると、クライアントが実行時に、現在オンラインセッションをホストまたはオンラインセッションに参加できるリージョンを判断できます。このアクションは、REST エンドポイントを指定して、指定の Multiplay フリートで現在利用可能な QoS サーバーを照会することで実行されます。
リクエストエンドポイントについては、次の URL で GET リクエストがサポートされています。
環境 | URL |
---|---|
運用 | https://qos.multiplay.com/v1/fleets/[fleet_id]/servers |
[fleet_id]
は、Multiplay によりご自身のタイトルに提供される実際のフリート ID に置き換えられます。リクエスト本文は空です。
#
レスポンスタイプ次のセクションに、リクエストから返される可能性のある HTTP レスポンスタイプの一覧を示します。
#
200 OKリクエストは成功したものの、If-None-Match ヘッダーで値と一致しない ETag が生成されました。
- レスポンスコンテンツタイプ:application/JSON
- レスポンス本文:「servers」と呼ばれる JSON 配列内の指定したフリートに関連付けられているフリートリージョン内のすべての QoS サーバーの一覧
配列内の各サーバーには以下のプロパティが含まれます。
プロパティ | 型 | 値 |
---|---|---|
location_id | Integer | Multiplay の位置 ID |
region_id | String | Multiplay のリージョン ID |
ipv4 | String | QoS サーバーのドットで 4 つに区切られたフォーマットの IPv4 アドレス(存在しない場合は空の文字列) |
ipv6 | String | QoS サーバーの RFC 4291 コロン区切りフォーマットの IPv6 アドレス(存在しない場合は空の文字列) |
port | Integer | IPv4/IPv6 サーバーがリクエストをリッスンしているポート。 |
各サーバーには IPv4 アドレス、IPv6 アドレス、またはその両方のタイプのアドレスが含まれます。ポートはいずれのバージョンの IP でも同じです。サーバーに特定の IP バージョンがない場合、次の例に示すように、空の文字列として表示されます。
#
304 Not Modifiedリクエストは成功し、生成またはキャッシュされた ETag が If-None-Match ヘッダーと一致します。ETag のサポートに関するドキュメントを参照してください。
- レスポンスタイプ:N/A
- レスポンス本文:なし
#
403 Forbiddenリクエストは認証されませんでした。
- レスポンスタイプ:text/plain *レスポンス本文:「REMOTE_ADDR のアクセスが拒否されました」(ここで、REMOTE_ADDR は呼び出し元のネットワークアドレス)
#
404 Not Found指定した fleet_id
が存在しません。
- レスポンスコンテンツタイプ:application/JSON
- レスポンス本文:エラーの関する詳細が記載された JSON オブジェクト
レスポンスには次のプロパティが含まれます。
プロパティ | 型 | 値 |
---|---|---|
success | Boolean | 古いプロパティ:操作が成功したかどうかを示す(常に false) |
error | Boolean | 古いプロパティ:操作でエラーが発生したかどうかを示す(常に true) |
error_code | Integer | Multiplay によって定義されたエラーコード(一般的に -1) |
error_message | String | エラーの理由に関する情報 |
messages | Array | Multiplay によって定義された状態メッセージの配列(現在は定義されていない) |
次のコードスニペットは、404 Not Found エラーの例を示します。
#
500 Internal Server Errorサーバー側でエラーが発生しました。
- レスポンスコンテンツタイプ:application/JSON
- レスポンス本文:404 Not Found と似ていますが、
error_message
に内部エラーの理由に関する情報が含まれます。
#
ETag のサポート成功した(2xx)Discovery サービスのレスポンスには、ETag レスポンスヘッダーに標準の HTTP エンティティタグが含まれます。このタグが後続のリクエストの If-None-Match
ヘッダー内で提供され、かつ変更がない場合、サーバーは HTTP ステータス 304(変更なし)と空の本文で応答します。これは、リストが最後のリクエスト以降変更されていないことを示します。このシナリオでは、前にクライアントでキャッシュされた結果を使用する必要があります。
#
Discovery に関するベストプラクティス- Discovery サービスは、ゲーム実行後の最初の QoS チェックの前に、一度接続される必要があります。結果をローカルにキャッシュし、提供された ETag を後続のリクエストで可能な限り使用します。このプロセスにより、サーバーリストに変更がないときに、レスポンス時間が改善され、ネットワークに流れるバイト数が減り、サーバーの負荷を減らすことができます。
- Discovery は 20 分程度の間隔で実行する必要があります。
- レスポンス内の「servers」配列には重複したエントリはありません。ただし、同じ QoS サーバー IP が複数のオーバーラップしているリージョンで機能する場合があることに注意してください。これを受けて、一意の各サーバーが 1 回だけ通信されるように分離してから、そのサーバーを使用する各リージョンの結果を使用できます。このプロセスにより、リクエストを送信してレスポンスを待つのにかかる時間を減らすことができます。
- ゲームクライアントが IPv4 接続のみに対応している場合は、IPv4 QoS サーバーに接続してください。逆に、ゲームクライアントが IPv6 接続のみに対応している場合は、IPv6 QoS サーバーに接続してください。ゲームクライアントが IP のバージョンに依存しない場合は、いずれかまたは両方のバージョンの QoS サーバーに接続できます。 *4xx と 5xx のレスポンスには、JSON オブジェクトに信頼してはならない古いプロパティが含まれています。代わりに、HTTP ステータスコードと error_message フィールドにのみ注目してください。
#
QoS サーバーQoS サーバーは、特定の専用サーバーリージョンへの通信品質を判定するために使用します。通信品質は、ネットワーク待ち時間とパケット損失の組み合わせとして定義されます。QoS サーバーは、非常にシンプルな UDP プロトコルによって動作します。リクエストに含まれるほぼすべてのデータは開発者が定義し、レスポンスには送信されたデータの完全なコピーが含まれます。たとえば、リクエストにタイムスタンプ、シーケンスカウンター、一意識別子を含め、レスポンスで待ち時間やパケット損失を計算し、重複するパケットを検出できます。
また、Discovery サービスによって特定された指定の IP アドレスとポートにある QoS サーバーに、QoS リクエストを直接送信することもできます。
現時点では、QoS リクエストのパケットを送信するのに必要な認証は存在しません。有効なリクエストを送信すれば、レスポンスが生成されます。ただし、サーバーの容量が足りており、クライアントがバンされておらず、かつそのリクエストまたはレスポンスが転送中に失われないことが前提です。
#
QoS リクエストQoS リクエストパケットは、クライアントから QoS サーバーに送信されます。ペイロード(IP と UDP ヘッダーの後)は、次の例に示すように定義されています。
名前 | サイズ | 値 | メモ |
Type | 1 バイト | 0x59 | パケットを有効な QoS リクエストパケットとして識別するマジック値。 |
VerAndFlow | 1 バイト | [0x00-0xF0] | 上位 4 ビットはバージョン用に予約されています。バージョンはゼロから始まり、パケットフォーマットのバージョンごとに 1 つずつ増えます(最大で 16 バージョン)。ここに記されているパケットフォーマットは、バージョン 0000b です。 下位 4 ビットはフロー制御用に予約されています。QoS リクエストの場合、フロー制御は常に 0000b に設定される必要があります。 |
Title | 不定 | 不定 | QoS をリクエストしているゲームのタイトル。タイトルの最初のバイトは、長さのバイトを含むタイトルブロックの長さです。つまり、タイトル「A」の長さのバイトは、その長さで 1、文字「A」で 1 の、合計で 2 になります。 タイトル自体は UTF8 エンコードされたバイトの配列で、文字列は NULL 終端になりません。たとえば、タイトル「ワオ」は [0x07, 0xe3, 0x83, 0xaf, 0xe3, 0x82, 0xaa] とエンコードされます。ここで、0x07 は長さです。 |
Custom | 不定 | 不定 | これはレスポンスでクライアントにエコーバックされるカスタムデータです。 |
ペイロード(IP と UDP ヘッダーを含まない)は、1,500 バイトを超えてはならないことに注意してください。パケットサイズの詳細については、QoS に関するベストプラクティスを参照してください。
次の例は、開発者がカスタムデータをどのように使用する可能性があるかについて示します1。
名前 | サイズ | 値 | メモ |
Sequence | 1 バイト | [0x00-0xFF] | この値は、特定の QoS チェックセッションで生成された QoS リクエストパケットごとに、0 から単調増加します。セッションは、同じ識別子を持つ単一の QoS(待ち時間 + パケット損失)チェックで発行されたすべてのパケットを網羅します。 |
Identifier | 2 バイト | 不定 | QoS チェック期間中に使用される一意の値。セッション内の各リクエストパケットは同じ識別子を使用します。 |
Timestamp | 8 バイト | 不定 | この値は、パケットが作成されたときのクライアントのエポックからのミリ秒数です。これはレスポンスに表示され、クライアントが大まかにミリ秒の精度でエンドツーエンドの待ち時間を判定できるようにします。 |
開発者はカスタムデータにこのフォーマット例を使用することも、別のカスタムフォーマットを使用することもできます。もう 1 つのオプションとして、ゲームで必要とされる場合に、1,500 バイトの上限を考慮しつつ、パケットをより大きなサイズにパディングして、大きな UDP パケットを破棄しない、ルート上にあるサーバーを優先することが挙げられます。
#
QoS レスポンスQoS レスポンスパケットは、ほぼ QoS リクエストパケット内のペイロードのバイトごとのコピーで、マジック値は QoS レスポンスパケットタイプに設定され、タイトルは削除されており、任意のフロー制御データセットがあります。QoS パケット内のデータはリクエストを送信したクライアントでのみ有用であるため、受け取ったデータをクライアントにエコーバックすることで、クライアントが QoS ベンチマーク全体を計算できます。
ペイロード(IP と UDP ヘッダーを含まない)は、2 から 1500 バイトになります。
名前 | サイズ | 値 | メモ |
Type | 1 バイト | 0x95 | パケットを有効な QoS リクエストパケットとして識別するマジック値。 |
VerAndFlow | 1 バイト | [0x00-0xFF] | 上位 4 ビットはバージョン用に予約されています。バージョンはゼロから始まり、パケットフォーマットのバージョンごとに 1 つずつ増えます(最大で 16 バージョン)。ここに記されているパケットフォーマットは、バージョン 0000b です。下位 4 ビットはフロー制御用に予約されています。 1000b は 2 分間のバン、1001b は 4 分間のバン、それ以降もユニットにつき 2 分ずつ増えます。両方のシナリオで、エッジケースが問題にならないように、クライアントは適切なバッファーを合計時間に追加する必要があります。 |
Custom | 不定 | 不定 | レスポンスでクライアントにエコーバックされる、リクエストからのカスタムデータ。 |
#
フロー制御フロー制御は、リクエストの送信から自発的にバックオフするようにサーバーからクライアントに指示すること、またはレスポンスの受け取りが一時的に制限されていることをクライアントに通知することとして定義されています。
QoS プロトコルは、開発者がデータのバイトオーダーを一切管理する必要がないように設計されました。ヘッダーデータはすべてバイトベースで、カスタムデータは送信されたときと同じバイトオーダーでエコーされます。したがって、バックオフの期間として潜在的な複数バイト値を使用するフロー制御の代わりに、そのコントラクトでは、フロー制御の各ユニットが 2 分間を表し、サーバーは単に適用するユニットの数を示します。クライアントはこの値を適切なバッファー時間分(たとえば、15 秒から 30 秒)パディングし、サーバーの待ち時間と処理時間に対処する必要があります。
自発的なバックオフとは、サーバーがクライアントに一定時間リクエストの送信を停止するよう依頼することです。自発的なバックオフ中でも、サーバーは引き続きクライアントに応答します。ただし、自発的なバックオフを依頼したサーバーにリクエストの送信を続行すると、クライアントが一時的にバンされる可能性があります。自発的なバックオフは現在使用されていないため、ゼロ以外のフロー制御はすべて、クライアントの一時的なバンを示す、1nnnb のバリエーションであることに注意してください。
バンされている間、バンされているクライアントからのすべての QoS リクエストは回答されません。バンが適用されるのは、クライアントがサーバーに短時間でパケットを送信し過ぎているため(QoS に関するベストプラクティスを参照)、またはサーバーの容量を超えているため、使用量を減らして容量以内に収めるアルゴリズムが適用されているためです。このシナリオでは、少しの間リクエストを受け入れないようにそのクライアントがランダムに選択されました。バンはサーバーごとであるため、1 台の QoS サーバーから一時的にバンされても、そのクライアントが他の QoS サーバーに通信することは妨げないことに注意してください。
#
QoS チェックに関するベストプラクティス- 単一の QoS チェックは、QoS サーバーに 10 件から 20 件のリクエストを送信してから、レスポンスを待つことを伴います。リクエストはバッチ処理することで、レスポンスを待つことなく連続して送信できます。レスポンスを待つ時間は、ゲームがどれくらいの待ち時間を許容するかと、ゲームフロー内で QoS のチェックにどれだけの時間専念できるかによって変わります。 *サーバーを 1 台ずつチェックする代わりに、開発者は一度に複数のサーバーにリクエストを送信してから、すべてのサーバーからすべてのレスポンスを待つようにすることができます。同時に通信するサーバーが多すぎると、レスポンスがソケットから読み取られるのに待ち時間が発生することがあるので注意してください。
- 1 件のリクエストのパケット長は 1,500 バイト(さらに IP と UDP ヘッダーを加えたサイズ)ですが、それほど大きなサイズの UDP パケットを送信することは一般的にはお勧めできません。断片化と再構築の対象となる UDP フレームのほうが、途中で中間ルーターによって破棄される可能性が高くなります。
- 途中でより大きな UDP パケットを破棄しているサーバーを特定するのに役立つように、QoS リクエストをゲームデータパケットのサイズに近くなるように十分なデータでパディングすることを検討してください。
- QoS は、ゲームセッションがオンライン以外のときに定期的な間隔で更新できますが、自動チェックの間には最低でも 3 分間必要です。ゲームセッションがオンラインのときは、クライアントに対する不要なネットワークトラフィックや QoS サーバーに対する負荷が発生しないように、QoS チェックを停止する必要があります。
- QoS をチェックしているときに、他のネットワークトラフィックを送信することは控えてください。他のネットワークトラフィックを処理するために時間がかかると、結果がおかしくなったり、待ち時間がさらに長くなったりするおそれがあります。
- QoS を推奨される最短間隔である 3 分間を下回る間隔で再チェックすることは、ネットワークをモバイルデータ通信から Wi-Fi やイーサネットに変更するなど、特定の状況では許容されます。これがほとんどまたはすべての QoS チェックが最短間隔を下回る間隔で発生している場合は、サーバーによって一時的にバンされるのを回避するために、基盤となるネットワークが安定するまで待ってから QoS チェックを再開することを検討してください。
#
ハウツー#
パケット損失を特定するパケット損失を特定するには、静的な数のリクエストを送信してから、レスポンスの数をカウントします。到着したレスポンスの数が送信したリクエストの数よりも少ない場合、パケットの損失が発生しています。
#
待ち時間を計算する待ち時間を計算するには、リクエストパケットにタイムスタンプを指定してから、レスポンスパケットごとにそのタイムスタンプを読み取って、それを現在の時間と比較します。その差を計算すると待ち時間が得られます。
#
重複したレスポンスを検出する重複したレスポンスを特定するには、各リクエストパケットに一意の値(例:シーケンスバイト)を指定します。レスポンスを記録するときに、その一意の値をリクエストで使用された値と照らし合わせてチェックします。レスポンスにすでに報告されているシーケンスが含まれる場合、それは重複であるためレスポンスの合計または待ち時間にカウントすることなく破棄できます。
#
古いレスポンスを特定する古いレスポンスを特定するには、単一のサーバーに送信される各リクエストのセットに静的な値を指定します。レスポンスを確認するときに、その静的な値が異なる場合、そのレスポンスは別の QoS チェックからの古いレスポンスです。新しいリクエストのセットで新しいチェックを開始するたびに値をローテーションさせてください。
#
QoS フローの例簡略化された QoS フローは、次の例のようになります。
フローは、プレイヤーがゲームを開始してオンラインメニューまたはモードに進むと(またはネットワークスタックが初期化されたときはいつでも)すぐに検出を開始します。検出が実行された後は、QoS のチェックが実行されます。オンラインゲームのセットアップ中に、前回のチェックから十分な時間が経過している場合は、QoS が定期的に再チェックされます。QoS 結果は、オンラインゲームのセットアップで、どのリージョンでゲームの作成または参加を試行するかについて判断するために使用されます。Multiplay 専用ホスティングで Multiplay マッチメイキングサービスを使用している場合、QoS 結果をマッチメイキングチケットにアタッチすることで、開発者のカスタムマッチ関数がそれらの結果に基づいて判断を下すことができます。詳細については、マッチメーカーベータ版ユーザーガイドを参照してください。
ゲームが終了し、プレイヤーが再度オンラインメニューまたはオンラインモードに入ると、フローはすでに実行済みであるため QoS の検出をスキップし、直接 QoS のチェックに進むことができます。開発者が QoS に直接進むのではなく、(最後の Discovery チェックから推奨される時間が経過した後に)再度 Discovery チェックを実行することを選択した場合は、前のチェックで指定された ETag を使用するようにしてください。