NAT P2P Interface

ユーザーが互いにデータを送受信するインターフェースと関連するネットワーク機能です。

15 分で読めます

P2P インターフェースにより Epic Online Services (EOS) SDK を実装するゲームで、ユーザー間の ピアツーピア (P2P) 接続 を設定して管理できるようになります。これにより、ユーザーが相互に直接データを送受信できるようになります。これは、通常マルチ プレイヤー ゲームで使用します。EOS P2P インターフェースで行う接続は、認証済みユーザー間でのみ確立され、デフォルトで DTLS を使用して保護されます。これには、わかりやすいメリットが 2 つあります。1つめ目は、EOS 認証で接続を再ネゴシエートする必要性が大幅に減ることから、P2P 接続処理が大幅に高速化します。2 つ目は、SDK のユーザーにとって接続を安全に処理するプロセス自体がとてもシンプルになることです。ネットワーク ソケットを細かく管理する必要性が抽象化され、どのデータを誰に送信すべきかに多くの機能が集約されます。

P2P インターフェースを利用する

EOS P2P インターフェースの関数を使用するには、最初に Platform (プラットフォーム) インターフェース 関数である EOS_Platform_GetP2PInterface から有効な EOS_HP2P ハンドルを取得する必要があり、このハンドルをすべての P2P インターフェース関数で使用します。Platform インターフェースと、この関数の詳細は「EOS Platform インターフェース」のページを参照してください。

P2P 接続を管理する

P2P インターフェースは、ピア間接続で使用するタイトル指定の識別子として EOS_P2P_SocketId 構造体を使用します。接続に関連する P2P 関数の多くが EOS_P2P_SocketId を必要とし、接続リクエストに関連付けたり、接続リクエストを返して受信した接続リクエストが関連付けられた接続を指定します。EOS_P2P_SocketId は次のパラメータで構成します。

パラメータ説明
ApiVersionバージョン フィールド。これは EOS_P2P_SOCKETID_API_LATEST に設定する必要があります。
SocketNameマルチ プレイヤー ゲームで不明なピアからの受信接続をすべて検証するために使用する値。

この SocketName フィールドは、すべての接続に共通の値を使用することも、マルチプレイヤー セッションで特定のプレイヤーだけが知っている秘密の値にすることもできます。承認された P2P 接続は、ユーザーの IP アドレスを接続先のピアに公開します。そのため接続リクエストを無闇に承認しないことが重要となります。

また通常、有効な EOS_ProductUserId は両方のユーザーに必要で、データの送信で自分が誰かを示し、またデータの送信先のユーザーを指定します。

明示的にオプションであることがマークされていない限り、P2P インターフェースの関数パラメータと関連する値はすべて必須です。これは、非同期関数やイベント応答のデータ出力によく使用する P2P インターフェースの出力パラメータも同様です。関数の戻り値の型が EOS_EResult で、その戻り値が EOS_Success でない場合、この関数が提供する出力パラメータに特に指定がない限りは設定されないことに注意が必要です。

接続をリクエストする

ローカル ユーザーが EOS_P2P_SendPacket 関数などでリモート ユーザーに情報を送信する場合、P2P インターフェースはこの 2 人のユーザー間の接続開始リクエストを自動で行い、その際に EOS_P2P_SocketId はこの接続の識別子として機能します。情報を送信するユーザーは SocketId に対して自分のリクエストを自動で承認しますが、情報を受信するユーザーはそれを承認する必要があり、通常は受信接続リクエストをリッスンして EOS_P2P_AcceptConnection 関数を使用します。

P2P 接続がまだ開始されていない場合、P2P 接続の開始に必要なすべての操作が P2P 接続のリクエストと承認の両方に使用できます。例えば、ローカル ユーザーが情報の送信に使用するソケット ID に対して既に作成済みの場合、リモート ユーザーと P2P 接続をリクエストする際に EOS_P2P_AcceptConnection を使用して、リモート ユーザーの P2P 接続要求を承認する際に EOS_P2P_SendPacket を使用できます。これは事実上、EOS_P2P_AcceptConnection を使用して、特定の SocketId で行われた次の接続リクエストを事前に承認できることを意味します。

特定のユーザーと複数の接続が開始している場合は、最初の接続のみをネゴシエートする必要があります。するとその後の接続リクエストでデータの受信速度が大幅に向上します。

接続リクエスト通知を受信する

ユーザーが接続リクエストを受信すると、バインド済みのすべての Peer Connection Request Handler (ピア接続リクエスト ハンドラ) に対して通知イベントが発生します。

新しいピア接続リクエスト ハンドラで接続リクエストをリッスンするには、EOS_P2P_AddNotifyPeerConnectionRequest を使用して受信接続リクエストの応答に使用する関数をバインドします。EOS_P2P_AddNotifyPeerConnectionRequest 関数が取るパラメータを以下に示します。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_AddNotifyPeerConnectionRequestOptions 構造体へのポインタ。
ClientData (オプション)イベント発生時に呼び出し元に返すデータへのポインタ。
ConnectionRequestHandlerピア接続リクエスト ハンドラーとして機能して受信接続リクエストに応答する関数。この関数にはパラメータとして EOS_P2P_OnIncomingConnectionRequestInfo 構造体へのポインタを必ず渡します。

EOS_P2P_AddNotifyPeerConnectionRequestOptions 構造体は以下のパラメータで構成されています。

パラメータ説明
ApiVersionバージョン フィールド。EOS_P2P_ADDNOTIFYPEERCONNECTIONREQUEST_API_LATEST に設定します。
LocalUserId受信接続リクエストをリッスンしているローカル ユーザーの ID に設定します。
SocketId (オプション)接続リクエストのフィルターに使用する有効な EOS_P2P_SocketId 構造体へのポインタ。

EOS_P2P_AddNotifyPeerConnectionRequest 関数は、成功すると有効な EOS_NotificationId を返し、失敗すると値 EOS_INVALID_NOTIFICATIONID を返します。

以下のパラメータを渡して EOS_P2P_RemoveNotifyPeerConnectionRequest 関数を使用し、ピア接続リクエスト ハンドラを削除できます。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
NotificationIdEOS_P2P_AddNotifyPeerConnectionRequest が返す有効な EOS_NotificationId で、削除するピア接続リクエスト ハンドラの特定に使用します。

接続を承認する

EOS_P2P_AcceptConnection 関数を使用してリクエストされた接続を承認したり、新しい接続リクエストを開始したりできます。接続を確立してデータ送信に使用する前に、双方のユーザーが必要な SocketId の接続を承認する必要があります。bDisableAutoAcceptConnectionEOS_TRUE に設定されている場合、接続を開始するためにはEOS_P2P_AcceptConnection を呼び出す必要があります。

EOS_P2P_AcceptConnection 関数の呼び出しには以下のパラメータを指定する必要があります。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_AcceptConnectionOptions 構造体へのポインタ。

EOS_P2P_AcceptConnectionOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionEOS_P2P_ACCEPTCONNECTION_API_LATEST に設定します。
LocalUserId接続を承認するローカル ユーザーの EOS_ProductUserId に設定します。
RemoteUserIdローカル ユーザーが接続する先の、リモート ユーザーの EOS_ProductUserId に設定します。
SocketId接続を承認する対象の、有効な EOS_P2P_SocketId 構造体へのポインタ。

指定した入力に無効なものがあると、EOS_P2P_AcceptConnection 関数は EOS_InvalidParameters の値を返します。提供した情報が有効な場合は EOS_Success を返して接続がローカルで承認されたことを通知し、リモート ユーザーが接続を承認するとデータを送信できるようになります。接続終了イベントが発生する前に、何度も EOS_P2P_AcceptConnection を呼び出しても効果はありません。

接続を終了する

EOS_P2P_CloseConnection 関数を使用して、リクエストされた接続を拒否したり、以前に特定のユーザーで承認済みの接続を終了したりできます。特定のユーザーとの接続をすべて閉じると、バッキング ソケット接続もすぐに破棄されます。この EOS_P2P_CloseConnection 関数には以下のパラメータが必要です。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_CloseConnectionOptions 構造体へのポインタ。

EOS_P2P_CloseConnectionOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionEOS_P2P_CLOSECONNECTION_API_LATEST に設定します。
LocalUserId接続を終了する、もしくは拒否するローカル ユーザーの EOS_ProductUserId に設定します。
RemoteUserId接続を終了されている、もしくは拒否されているリモート ユーザーの EOS_ProductUserId に設定します。
SocketId接続を終了する、もしくは拒否する、有効な EOS_P2P_SocketId 構造体へのポインタ。

EOS_P2P_CloseConnection 関数は、指定した関数の入力が無効なことを示す EOS_InvalidParameters の値を返すか、もしくは指定した入力が有効で接続が終了したか、接続リクエストがサイレントで拒否されたことを示す EOS_Success の値を返します。

EOS_P2P_CloseConnections 関数を使用すると、特定のユーザーからの接続ではなく、特定の SocketId 上の接続をすべて終了したり拒否したりできます。これはセッションの終了時に、そのセッションに関連する接続をすべて破棄する場合に使用できます。この EOS_P2P_CloseConnections 関数には以下のパラメータが必要です。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_CloseConnectionsOptions 構造体へのポインタ。

EOS_P2P_CloseConnectionsOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionEOS_P2P_CLOSECONNECTIONS_API_LATEST に設定します。
LocalUserIdリクエストの SocketId との接続をすべて終了するローカル ユーザーの EOS_ProductUserId に設定します。
SocketId (オプション)接続リクエストのフィルターに使用する有効な EOS_P2P_SocketId 構造体へのポインタ。

指定した入力に無効なものがあると、この関数は EOS_InvalidParameters の結果を返します。または提供した情報が有効で、指定した SocketId との接続がすべて正常に終了した場合は EOS_Success を返します。

接続終了通知を受信する

開始した接続や保留中の接続が終了すると Connection Closed Event (接続終了イベント) が発生して、アプリケーションに通知して応答を許可します。接続終了イベントのハンドラを作成するには、以下のパラメータを設定して EOS_P2P_AddNotifyPeerConnectionClosed 関数を使用します。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_AddNotifyPeerConnectionClosedOptions 構造体へのポインタ。
ClientData (オプション)イベント発生時に呼び出し元に返すデータへのポインタ。
ConnectionClosedHandler接続終了イベントの発生時に呼び出す関数。この関数は、パラメータとして渡す EOS_P2P_OnRemoteConnectionClosedInfo 構造体へのポインタを受け取る必要がある。

EOS_P2P_AddNotifyPeerConnectionClosedOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionEOS_P2P_ADDNOTIFYPEERCONNECTIONCLOSED_API_LATEST に設定します。
LocalUserId接続の終了をリッスンしているローカル ユーザーの EOS_ProductUserId に設定します。
SocketId (オプション)接続終了イベントをフィルターする対象の、有効な EOS_P2P_SocketId 構造体へのポインタ。

この EOS_P2P_AddNotifyPeerConnectionClosed 関数は、接続終了イベント ハンドラの特定に使用する EOS_NotificationId を返します。

以下のパラメータを使用して関数 EOS_P2P_RemoveNotifyPeerConnectionClosed を呼び出すと、接続終了イベント ハンドラを削除できます。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
NotificationIdEOS_P2P_AddNotifyPeerConnectionClosed が返す有効な EOS_NotificationId

P2P 接続を介してデータを送受信する

P2P 接続が正常に確立されると、それを利用してユーザーがデータを送受信できます。

データを送信する

EOS_P2P_SendPacket 関数はパケットを別のユーザーに安全に送信します。そのピアに既に開始した接続がある場合は、すぐに送信します。既に開始した接続がない場合は、新しい接続のリクエストを行います。EOS_P2P_SendPacket 関数が取るパラメータを以下に示します。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_SendPacketOptions 構造体へのポインタ。

EOS_P2P_SendPacketOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionEOS_P2P_SENDPACKET_API_LATEST に設定します。
LocalUserIdパケットを送信するローカル ユーザーの EOS_ProductUserId に設定します。
RemoteUserIdパケットを送信する先のリモート ユーザーの EOS_ProductUserId に設定します。
SocketId有効な EOS_P2P_SocketId へのポインタ。
Channelこのデータを送信するチャンネルに設定します。
DataLengthBytesData から送信するバイト数を設定します。
DataDataLengthBytes の送信元データの、バッファの先頭へのポインタ。
bAllowDelayedDeliveryこれが false で既に確立された接続がない場合、パケットを通知なしで破棄します。それ以外の場合は、接続を開始するまで、または EOS_P2P_CloseConnectionEOS_P2P_CloseConnections を使用して接続を終了するまで、パケットをキューに入れます。
Reliabilityこのパケットの配信の信頼性を設定します。信頼性は EOS_PR_UnreliableUnorderedEOS_PR_ReliableUnorderedEOS_PR_ReliableOrdered です。
bDisableAutoAcceptConnectiontrue の場合、EOS_P2P_SendPacketRemoteUserId で自動的に接続を確立しません。従って、接続が終了した場合は最初に EOS_P2P_AcceptConnection を呼び出す必要があります。false の場合、接続が開始されていない限り、EOS_P2P_SendPacket は呼び出されると常に接続を受け取り開始します。

この関数は、指定した入力に無効なものがある場合は EOS_InvalidParameters を返し、指定した情報が有効で送信できた場合は EOS_Success を返します。ただし、成功を示す戻り値は、正常に送達したかどうかではなく、パケットを正常に送信できることだけを表します。不確かな方法でデータを送信するため、確実に伝達されるとは限りません。

データを受信する

P2P インターフェースはユーザーが内部で受信したパケットをキューに入れ、EOS_P2P_ReceivePacket 関数の呼び出しを受けるとデータをキューから削除してバッファに格納します。この関数が取るパラメータを以下に示します。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
Options有効な EOS_P2P_ReceivePacketOptions 構造体へのポインタ。
OutPeerIdこのパケットの送信者を書き出す EOS_ProductUserId 値へのポインタ。
OutSocketId関連する SocketId データを書き込む EOS_P2P_SocketId 構造体へのポインタ。
OutChannelこのパケットに関連付けられたチャンネルを書き込む uint8_t へのポインタ。
OutData受信したパケットが含むデータを書き込むバッファへのポインタ。このバッファのサイズには、この関数に対する OptionsMaxDataSizeBytes を指定します。
OutBytesWrittenOutData に書き込んだバイト数を記録する uint32_t へのポインタ。

EOS_P2P_ReceivePacketOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionバージョン フィールド。EOS_P2P_RECEIVEPACKET_API_LATEST に設定します。
LocalUserId受信したパケットを要求しているローカル ユーザーの EOS_ProductUserId に設定します。
MaxDataSizeBytesOutData バッファに安全に書き込める最大バイト数。
RequestedChannel (オプション)設定するとこのチャンネルに属するパケットのみを受信します。

入力したパラメータに無効なものがあると、この関数は EOS_InvalidParameters を返します。パケットと関連するデータをすべての出力パラメータに正常にコピーした場合は EOS_Success を返します。リクエストを満たす該当するパケットがない場合は EOS_NotFound を返します。この関数が EOS_Success の値を返す時だけ出力パラメータに書き込みが行われるということに注意してください。

EOS_P2P_ReceivePacketOptions では、MaxDataSizeBytes でバッファに書き込めるデータ量と、OutData でバッファ自体を指定する必要があります。提供したバッファの容量が足りず、次のパケットが収まらない場合、通知なしで提供したバッファの容量までデータを切り捨てます。つまり MaxDataSizeBytes でサイズ 0 を指定して OutDataNULL のバッファを提供すると、パケットのデータを完全に破棄できます。EOS_P2P_MAX_PACKET_SIZE のバッファを安全に使用してパケット データを格納することもできます。そのためには EOS_P2P_ReceivePacket の前に EOS_P2P_GetNextReceivedPacketSize を呼び出して、パケット データの正確なサイズを取得することを推奨します。DTLS/SCTP/UDP パケット オーバーヘッドのため、EOS_P2P_MAX_PACKET_SIZE は 1170 です。

EOS_P2P_RecievePacket を頻繁に呼び出して、内部パケット キューが満杯になることを回避します。内部パケット キューが満杯になると、受信パケットは受け取られることなく破棄されます。

パケット サイズを決定する

EOS_P2P_GetNextReceivedPacketSize は内部キューにある次のパケット サイズを、キューから削除することなくバイト単位で取得します。必要なパラメータは以下です。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_GetNextReceivedPacketSizeOptions 構造体へのポインタ。
OutPacketSizeBytes関数を呼び出したユーザーに対する次のパケット サイズを格納する uint32_t へのポインタ。

EOS_P2P_GetNextReceivedPacketSizeOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionEOS_P2P_GETNEXTRECEIVEDPACKETSIZE_API_LATEST に設定します。
LocalUserId次のパケット サイズを要求するローカル ユーザーの EOS_ProductUserId に設定します。
RequestedChannel (オプション)設定すると、このチャンネルに属する次のパケット サイズのみを返します。

この関数は、入力パラメータに無効なものがあると EOS_InvalidParameters の値を返し、パケットのデータ サイズが OutPacketSizeBytes に正常にコピーされると EOS_Success の値を返します。対象のデータがない場合、この関数は代わりに EOS_NotFound の値を返します。

NAT タイプを決定する

P2P インターフェースは NAT トラバーサルを行いますが、制限付き NAT を持つピアがいくつもある場合は受信した接続を常に確立できるとは限りません。この場合はリレーが必要で、NAT トラバーサルで失敗する場合は自動で使用します。P2P インターフェースはインターネットに関連するローカル ユーザーの NAT タイプ をクエリし、ユーザーが簡単に接続できるピアかどうかを判断します。これは EOS_ENATType で表され、以下の値をとります。

説明
EOS_NAT_UnknownNAT タイプが現在不明であるか、もしくは正確に判別できません。
EOS_NAT_Openすべてのタイプのピアを直接接続できます。
EOS_NAT_Moderateリレー サーバーを使用せずに、モデレートやオープン状態の他のピアに直接接続できます。
EOS_NAT_Strictリレー サーバーを使用せずに、オープン状態のピアにのみ直接接続できます。

EOS_P2P_QueryNATType 関数は、現在の接続の NAT タイプを非同期で判断します。この方法は、まずリモート サーバーに複数のデータ パケットを送信して、そうしたサーバーがローカル アプリケーションが使用する IP とポートについて応答を返します。リクエストの処理中に EOS_P2P_QueryNATType をさらに呼び出しても、最初のリクエストにグループ化されて新たなリクエストが開始しないことに注意が必要です。EOS_P2P_QueryNATType は以下のパラメータを取ります。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_QueryNATTypeOptions 構造体へのポインタ。
ClientData (オプション)クエリの終了時に呼び出し元に返すデータへのポインタ。
NATTypeQueriedHandlerクエリの終了時に呼び出す関数へのポインタ。

EOS_P2P_QueryNATTypeOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionバージョン フィールド。EOS_P2P_QUERYNATTYPE_API_LATEST に設定します。

NAT タイプのクエリは非同期なので、この関数は値を直接返しません。代わりにこの関数は、クエリの終了時に呼び出すように登録した関数 NAT Type Queried Handler でユーザーの NAT タイプを出力します。このクエリがユーザーの NAT タイプを判別できない場合は、EOS_NAT_Unknown の値を返します。

EOS_P2P_QueryNATType が完了するとユーザーの NAT タイプの値がキャッシュされるので、関数 EOS_P2P_GetNATType を代わりに呼び出してこの値をすぐに返すことができます。これが正常に返されるのは EOS_P2P_QueryNATType が少なくとも 1 回は完了した場合のみです。EOS_P2P_GetNATType 関数の呼び出しには以下のパラメータを指定する必要があります。

パラメータ説明
HandlePlatform インターフェースから受信した有効な EOS_HP2P ハンドル。
OptionsEOS_P2P_GetNATTypeOptions 構造体へのポインタ。
OutNATType以前に EOS_P2P_QueryNATType でクエリしたキャッシュ値に設定する EOS_ENATType オブジェクトへのポインタ。

EOS_P2P_GetNATTypeOptions 構造体は以下のパラメータを含みます。

パラメータ説明
ApiVersionEOS_P2P_GETNATTYPE_API_LATEST に設定します。

過去に EOS_P2P_QueryNATType を正常に呼び出した場合は EOS_P2P_GetNATType 関数が EOS_Success を返します。これまでに EOS_P2P_QueryNATType を呼び出していない場合、または完了したことがない場合は、EOS_NotFound を返します。