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
関数が取るパラメータを以下に示します。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_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
関数を使用し、ピア接続リクエスト ハンドラを削除できます。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
NotificationId | EOS_P2P_AddNotifyPeerConnectionRequest が返す有効な EOS_NotificationId で、削除するピア接続リクエスト ハンドラの特定に使用します。 |
接続を承認する
EOS_P2P_AcceptConnection
関数を使用してリクエストされた接続を承認したり、新しい接続リクエストを開始したりできます。接続を確立してデータ送信に使用する前に、双方のユーザーが必要な SocketId の接続を承認する必要があります。bDisableAutoAcceptConnection
が EOS_TRUE
に設定されている場合、接続を開始するためにはEOS_P2P_AcceptConnection
を呼び出す必要があります。
EOS_P2P_AcceptConnection
関数の呼び出しには以下のパラメータを指定する必要があります。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_P2P_AcceptConnectionOptions 構造体へのポインタ。 |
EOS_P2P_AcceptConnectionOptions
構造体は以下のパラメータを含みます。
パラメータ | 説明 |
---|---|
ApiVersion | EOS_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
関数には以下のパラメータが必要です。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_P2P_CloseConnectionOptions 構造体へのポインタ。 |
EOS_P2P_CloseConnectionOptions
構造体は以下のパラメータを含みます。
パラメータ | 説明 |
---|---|
ApiVersion | EOS_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
関数には以下のパラメータが必要です。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_P2P_CloseConnectionsOptions 構造体へのポインタ。 |
EOS_P2P_CloseConnectionsOptions
構造体は以下のパラメータを含みます。
パラメータ | 説明 |
---|---|
ApiVersion | EOS_P2P_CLOSECONNECTIONS_API_LATEST に設定します。 |
LocalUserId | リクエストの SocketId との接続をすべて終了するローカル ユーザーの EOS_ProductUserId に設定します。 |
SocketId (オプション) | 接続リクエストのフィルターに使用する有効な EOS_P2P_SocketId 構造体へのポインタ。 |
指定した入力に無効なものがあると、この関数は EOS_InvalidParameters
の結果を返します。または提供した情報が有効で、指定した SocketId
との接続がすべて正常に終了した場合は EOS_Success
を返します。
接続終了通知を受信する
開始した接続や保留中の接続が終了すると Connection Closed Event (接続終了イベント) が発生して、アプリケーションに通知して応答を許可します。接続終了イベントのハンドラを作成するには、以下のパラメータを設定して EOS_P2P_AddNotifyPeerConnectionClosed
関数を使用します。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_P2P_AddNotifyPeerConnectionClosedOptions 構造体へのポインタ。 |
ClientData (オプション) | イベント発生時に呼び出し元に返すデータへのポインタ。 |
ConnectionClosedHandler | 接続終了イベントの発生時に呼び出す関数。この関数は、パラメータとして渡す EOS_P2P_OnRemoteConnectionClosedInfo 構造体へのポインタを受け取る必要がある。 |
EOS_P2P_AddNotifyPeerConnectionClosedOptions
構造体は以下のパラメータを含みます。
パラメータ | 説明 |
---|---|
ApiVersion | EOS_P2P_ADDNOTIFYPEERCONNECTIONCLOSED_API_LATEST に設定します。 |
LocalUserId | 接続の終了をリッスンしているローカル ユーザーの EOS_ProductUserId に設定します。 |
SocketId (オプション) | 接続終了イベントをフィルターする対象の、有効な EOS_P2P_SocketId 構造体へのポインタ。 |
この EOS_P2P_AddNotifyPeerConnectionClosed
関数は、接続終了イベント ハンドラの特定に使用する EOS_NotificationId
を返します。
以下のパラメータを使用して関数 EOS_P2P_RemoveNotifyPeerConnectionClosed
を呼び出すと、接続終了イベント ハンドラを削除できます。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
NotificationId | EOS_P2P_AddNotifyPeerConnectionClosed が返す有効な EOS_NotificationId 。 |
P2P 接続を介してデータを送受信する
P2P 接続が正常に確立されると、それを利用してユーザーがデータを送受信できます。
データを送信する
EOS_P2P_SendPacket
関数はパケットを別のユーザーに安全に送信します。そのピアに既に開始した接続がある場合は、すぐに送信します。既に開始した接続がない場合は、新しい接続のリクエストを行います。EOS_P2P_SendPacket
関数が取るパラメータを以下に示します。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_P2P_SendPacketOptions 構造体へのポインタ。 |
EOS_P2P_SendPacketOptions
構造体は以下のパラメータを含みます。
パラメータ | 説明 |
---|---|
ApiVersion | EOS_P2P_SENDPACKET_API_LATEST に設定します。 |
LocalUserId | パケットを送信するローカル ユーザーの EOS_ProductUserId に設定します。 |
RemoteUserId | パケットを送信する先のリモート ユーザーの EOS_ProductUserId に設定します。 |
SocketId | 有効な EOS_P2P_SocketId へのポインタ。 |
Channel | このデータを送信するチャンネルに設定します。 |
DataLengthBytes | Data から送信するバイト数を設定します。 |
Data | DataLengthBytes の送信元データの、バッファの先頭へのポインタ。 |
bAllowDelayedDelivery | これが false で既に確立された接続がない場合、パケットを通知なしで破棄します。それ以外の場合は、接続を開始するまで、または EOS_P2P_CloseConnection や EOS_P2P_CloseConnections を使用して接続を終了するまで、パケットをキューに入れます。 |
Reliability | このパケットの配信の信頼性を設定します。信頼性は EOS_PR_UnreliableUnordered 、EOS_PR_ReliableUnordered 、EOS_PR_ReliableOrdered です。 |
bDisableAutoAcceptConnection | true の場合、EOS_P2P_SendPacket は RemoteUserId で自動的に接続を確立しません。従って、接続が終了した場合は最初に EOS_P2P_AcceptConnection を呼び出す必要があります。false の場合、接続が開始されていない限り、EOS_P2P_SendPacket は呼び出されると常に接続を受け取り開始します。 |
この関数は、指定した入力に無効なものがある場合は EOS_InvalidParameters
を返し、指定した情報が有効で送信できた場合は EOS_Success
を返します。ただし、成功を示す戻り値は、正常に送達したかどうかではなく、パケットを正常に送信できることだけを表します。不確かな方法でデータを送信するため、確実に伝達されるとは限りません。
データを受信する
P2P インターフェースはユーザーが内部で受信したパケットをキューに入れ、EOS_P2P_ReceivePacket
関数の呼び出しを受けるとデータをキューから削除してバッファに格納します。この関数が取るパラメータを以下に示します。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | 有効な EOS_P2P_ReceivePacketOptions 構造体へのポインタ。 |
OutPeerId | このパケットの送信者を書き出す EOS_ProductUserId 値へのポインタ。 |
OutSocketId | 関連する SocketId データを書き込む EOS_P2P_SocketId 構造体へのポインタ。 |
OutChannel | このパケットに関連付けられたチャンネルを書き込む uint8_t へのポインタ。 |
OutData | 受信したパケットが含むデータを書き込むバッファへのポインタ。このバッファのサイズには、この関数に対する Options の MaxDataSizeBytes を指定します。 |
OutBytesWritten | OutData に書き込んだバイト数を記録する uint32_t へのポインタ。 |
EOS_P2P_ReceivePacketOptions
構造体は以下のパラメータを含みます。
パラメータ | 説明 |
---|---|
ApiVersion | バージョン フィールド。EOS_P2P_RECEIVEPACKET_API_LATEST に設定します。 |
LocalUserId | 受信したパケットを要求しているローカル ユーザーの EOS_ProductUserId に設定します。 |
MaxDataSizeBytes | OutData バッファに安全に書き込める最大バイト数。 |
RequestedChannel (オプション) | 設定するとこのチャンネルに属するパケットのみを受信します。 |
入力したパラメータに無効なものがあると、この関数は EOS_InvalidParameters
を返します。パケットと関連するデータをすべての出力パラメータに正常にコピーした場合は EOS_Success
を返します。リクエストを満たす該当するパケットがない場合は EOS_NotFound
を返します。この関数が EOS_Success
の値を返す時だけ出力パラメータに書き込みが行われるということに注意してください。
EOS_P2P_ReceivePacketOptions
では、MaxDataSizeBytes
でバッファに書き込めるデータ量と、OutData
でバッファ自体を指定する必要があります。提供したバッファの容量が足りず、次のパケットが収まらない場合、通知なしで提供したバッファの容量までデータを切り捨てます。つまり MaxDataSizeBytes
でサイズ 0 を指定して OutData
が NULL
のバッファを提供すると、パケットのデータを完全に破棄できます。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
は内部キューにある次のパケット サイズを、キューから削除することなくバイト単位で取得します。必要なパラメータは以下です。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_P2P_GetNextReceivedPacketSizeOptions 構造体へのポインタ。 |
OutPacketSizeBytes | 関数を呼び出したユーザーに対する次のパケット サイズを格納する uint32_t へのポインタ。 |
EOS_P2P_GetNextReceivedPacketSizeOptions
構造体は以下のパラメータを含みます。
パラメータ | 説明 |
---|---|
ApiVersion | EOS_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_Unknown | NAT タイプが現在不明であるか、もしくは正確に判別できません。 |
EOS_NAT_Open | すべてのタイプのピアを直接接続できます。 |
EOS_NAT_Moderate | リレー サーバーを使用せずに、モデレートやオープン状態の他のピアに直接接続できます。 |
EOS_NAT_Strict | リレー サーバーを使用せずに、オープン状態のピアにのみ直接接続できます。 |
EOS_P2P_QueryNATType
関数は、現在の接続の NAT タイプを非同期で判断します。この方法は、まずリモート サーバーに複数のデータ パケットを送信して、そうしたサーバーがローカル アプリケーションが使用する IP とポートについて応答を返します。リクエストの処理中に EOS_P2P_QueryNATType
をさらに呼び出しても、最初のリクエストにグループ化されて新たなリクエストが開始しないことに注意が必要です。EOS_P2P_QueryNATType
は以下のパラメータを取ります。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_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
関数の呼び出しには以下のパラメータを指定する必要があります。
パラメータ | 説明 |
---|---|
Handle | Platform インターフェースから受信した有効な EOS_HP2P ハンドル。 |
Options | EOS_P2P_GetNATTypeOptions 構造体へのポインタ。 |
OutNATType | 以前に EOS_P2P_QueryNATType でクエリしたキャッシュ値に設定する EOS_ENATType オブジェクトへのポインタ。 |
EOS_P2P_GetNATTypeOptions
構造体は以下のパラメータを含みます。
パラメータ | 説明 |
---|---|
ApiVersion | EOS_P2P_GETNATTYPE_API_LATEST に設定します。 |
過去に EOS_P2P_QueryNATType
を正常に呼び出した場合は EOS_P2P_GetNATType
関数が EOS_Success
を返します。これまでに EOS_P2P_QueryNATType
を呼び出していない場合、または完了したことがない場合は、EOS_NotFound
を返します。