Steam ネットワーキングでプレイヤーどうしをつなぐ手順|API の種類・リレー
Steam ネットワーキングは、プレイヤー間のメッセージ通信に使えるいくつかの API の集まりです。最新の API は、デフォルトで Valve のネットワークを介してパケットをリレーし、通常の UDP 接続もサポートしています。
このページの目次
プレイヤー間の通信に使う API の集まり
Steam ネットワーキングは、プレイヤー間のメッセージ通信に使えるいくつかの API の集まりです。最新の API は、デフォルトで Valve のネットワークを介してパケットをリレーし、通常の UDP 接続もサポートしています。オープンソース版は GitHub から入手できます。ただし、オープンソース版のコードは、リレーネットワークへのアクセスをサポートしていません。
Valve のネットワークを使用するには、Steam パートナーとなり、Steamworks SDK のバージョンを使用する必要があります。
API の種類と役目
Steam ネットワーキングに含まれる API とサービスの役目は、次のとおりです。
| 名前 | 役目 |
|---|---|
ISteamNetworkingMessages |
任意のピアにメッセージを送信するための高レベルインターフェイスです。接続ハンドルを使用しない点で UDP に似ていて、sendto ソケット関数と同様に、メッセージを送信するたびに受信者を指定します。 |
ISteamNetworkingSockets |
メッセージ送受信用の低レベルの、接続ハンドル指向のインターフェイスです。 |
ISteamNetworkingUtils |
任意のインターネットホスト間の ping 時間を推定するためのツールなど、さまざまなユーティリティがあります。 |
steamnetworkingtypes |
多くの一般的なタイプとユーティリティを備えたヘッダーです。 |
| Steam データグラムリレー | ゲームトラフィックを Valve のバックボーンを介してリレーするサービスです。IP アドレスが公開されることを避けられます。すべての P2P 接続は、必要に応じて自動的に Valve のバックボーンを介してリレーされます。 |
ISteamNetworking |
非推奨の古い API です。今後のリリースでこの API を SDK から削除する可能性があります。 |
ISteamNetworkingMessages では、1つのピアを「クライアント」として選択して接続を開始する必要はなく、サーバーはクライアント接続を「リッスン」したり「受け入れ」たりする必要はありません。どちらのピアもすぐにメッセージを送信できます。生の UDP とは異なり、単一パケットよりも大きなメッセージや、信頼できるメッセージの送信をサポートしています。トラフィックは、Valve のバックボーンを介してリレーされ、必要な場合は直接接続が確立されます。
ISteamNetworkingSockets の特徴
ISteamNetworkingSockets は、バークレーソケットに似た、ゲーム用のネットワーク API です。TCP のようなコネクション指向の API で、メッセージの送受信では、ピアを接続ハンドルで識別します。TCP とは異なり、ストリーム指向ではなくメッセージ指向で、メッセージ間の境界は API によって維持されます。信頼性のあるメッセージと信頼性のないメッセージの両方をサポートしています。
Valve のネットワークを介した中継接続をサポートしていて、IP アドレスが公開されることを防ぎます。IPv4 または IPv6 を使用して、プレーン UDP 経由の標準接続もサポートします。メンバー関数は、グローバルアクセサー関数 SteamNetworkingSockets 経由で呼び出されます。
ISteamNetworkingMessages は UDP スタイルのインターフェイスで、接続を最初に確立するのではなく、各送信呼び出しで宛先ピアを特定します。同じ接続が内部で引き続き使用されますが、接続の作成とアイドルタイムアウトは自動であり、接続の制御や、その状態に関するフィードバックはあまり得られません。
ISteamNetworkingSockets で接続する流れ
接続の流れは、次の順です。
- 待ち受ける。 サーバー側が、
CreateListenSocketP2PかCreateListenSocketIPを呼び出します。CreateListenSocketP2PはクライアントがConnectP2Pを使用して接続するソケットで、接続は Valve のネットワークを介して中継されます。CreateListenSocketIPは、通常の UDP(IPv4 または IPv6)経由でクライアントの接続をリッスンする「サーバー」ソケットを作成し、クライアントはConnectByIPAddressを呼び出して接続します。 - 接続を開く。 クライアント側が、
ConnectP2PかConnectByIPAddressを呼び出します。ConnectP2Pは、プラットフォーム固有の識別子を使用して識別されたピアへの接続を開始します。トラフィックは、Steam データグラムリレーネットワークを介して中継されます。これを使用する場合、アプリの初期化時にISteamNetworkingUtils::InitRelayNetworkAccessを呼び出す必要があるでしょう。ConnectByIPAddressは、指定された IPv4 または IPv6 アドレスで UDP 経由の「サーバー」との通信を開始します。リモートホストは、指定されたポートでCreateListenSocketIPを呼び出してリッスンしている必要があります。接続を開始するとSteamNetConnectionStatusChangedCallback_tコールバックがトリガーされ、タイムアウトまたは接続成功時にも、コールバックが再びトリガーされます。 - 受け入れる。 クライアントが接続を試みると、接続が
k_ESteamNetworkingConnectionState_Connectingの状態で作成され、SteamNetConnectionStatusChangedCallback_tがポストされます。この時点で、アプリケーションはAcceptConnectionで接続を受け入れるか、閉じる必要があります(無視はできません)。接続を受け入れると、クライアントに接続したことを通知する応答が送信されるため、1~2秒以内にアクションを実行する必要があります。アプリケーションがコールバックを処理しない状態が数秒以上続くと(例:マップのロード中)、クライアントがそのインターバル中に接続を試み、タイムアウトにより接続に失敗する可能性があります。 - 送る。
SendMessageToConnectionが、指定の接続上のリモートホストにメッセージを送信します。nSendFlagsが配信保証を決め、たとえばk_nSteamNetworkingSend_Unreliable・k_nSteamNetworkingSend_Reliable・k_nSteamNetworkingSend_NoNagle・k_nSteamNetworkingSend_NoDelayなどがあります。メッセージに使用するセマンティックは、標準の「ストリーム」ソケット(SOCK_STREAM)のセマンティックとまったく同じではありません。ここで使用されるメッセージのセマンティックでは、各送信呼び出しが、リモートホスト上で成功した読み取り呼び出しと1対1で一致します。SendMessagesは、メッセージペイロードをコピーせずに1つ以上のメッセージを送信します。この関数を使用するには、まずISteamNetworkingUtils::AllocateMessageを使用してメッセージオブジェクトを割り当てる必要があります。 - 受け取る。
ReceiveMessagesOnConnectionが、接続上で利用可能なメッセージがあれば、次のメッセージを取得します。配列に返されるメッセージの数(最大nMaxMessages)を返し、接続ハンドルが無効な場合は -1、データがない場合は 0 が返されます。信頼性の高いメッセージは、送信された順に受信されます。信頼性の低いメッセージは、破棄されたり、他のメッセージとの相対的な順序、または信頼性の高いメッセージとの相対的な順序に沿って送信されなかったりする場合があります。メッセージが返された場合は、それぞれにSteamNetworkingMessage_t::Releaseを呼び出して、完了後にリソースを解放する必要があります。多数の接続を効率的にポーリングするには、ポーリンググループを使います。CreatePollGroupで作成し、ReceiveMessagesOnPollGroupが、ポーリンググループ内のいずれかの接続で利用可能な次のメッセージを返します。完了したら、DestroyPollGroupを使用してポーリンググループを破棄する必要があります。 - 閉じる。
CloseConnectionが、リモートホストとの接続を切断し、接続ハンドルを無効にします。接続上の未読データはすべて破棄されます。bEnableLingerでソケットを「残存」状態にすると、接続は、実際に接続を閉じる前に、残りの信頼できる送信メッセージの配信を試みます。そうでない場合、未送信の信頼できるデータはすべて破棄されます。リスニングソケットはCloseListenSocketで破棄し、そのリスニングソケットで受け入れられたすべての接続が、正常に終了することなく切断されます。
Steam データグラムリレー(SDR)
Steam データグラムリレー(SDR)は、Valve の仮想プライベートゲーミングネットワークです。API を使用すると、ゲームトラフィックを Valve のゲームコンテンツ専用バックボーンに伝送でき、リレーネットワークにもアクセスできるようになります。トラフィックをリレーすると、IP アドレスが公開されないため、サーバーやプレイヤーを DoS 攻撃から守ることができます。ゲームが受け取るトラフィックはすべて、認証され、暗号化され、レート制限がかけられます。このリレーネットワークは、ピアツーピアのトラフィックと専用サーバーの両方に使用できます。
ピアツーピアのトラフィックで SDR を使用するには、Steam では ISteamNetworkingSockets::CreateListenSocketP2P や ISteamNetworkingSockets::ConnectP2P のような API を使用するだけで、それ以外は Steam が処理します。
ピアツーピアの API は、1つのピアが専用サーバーの場合でも動作します。ただし、リレーを実行しているデータセンターの近くにゲームの専用サーバーがないと、最適なリレールートがデフォルトの IP ルートよりも遅くなる場合があり、一部のプレイヤーにとって遅延が現状より悪化します。既知のデータセンターで実行されるサーバーは、特別な API を使用して接続します。このユースケースは、SDK では「ホストされた専用サーバー(Hosted Dedicated Server)」と呼ばれます。
プレイヤーをサーバーに割り当てる中央のマッチメイキング/ログインサービス(ゲームコーディネーター)がない場合や、できるだけ処理をシンプルにしたい場合は、CreateListenSocketP2P と ConnectP2P を使用して、既知のデータセンターにある専用サーバーに接続できます。この場合、通常の P2P 接続と同様に、クライアント側で接続が開始されます。ランデブーメッセージは Steam 経由で送信されるため、プレイヤーやサーバーが Steam との接続を失うと、接続を確立できなくなります。
ゲームコーディネーターがある場合は、チケットを使う接続の流れもあります。サーバーは ISteamNetworkingSockets::CreateHostedDedicatedServerListenSocket でリレーされたトラフィックのリッスンを開始します。ゲームコーディネーターは、クライアントによるサーバーへの接続を許可する準備ができると、SteamDatagramRelayAuthTicket を生成して秘密鍵で署名し、クライアントに送ります。このチケットは、特定のクライアントが特定のゲームサーバーと限られた時間内に通信することを許可します。クライアントは ISteamNetworkingSockets::ConnectToHostedDedicatedServer でサーバーに接続します。
ほとんどの場合、ゲームが基本的な条件を満たしていれば、他のプラットフォームやストアにいるプレイヤーもリレーネットワークにアクセスできます。条件には、Steam でゲームのバージョンを配信していることや、何らかのマッチメイキングサービスを使用して認証資格情報を発行できることなどがあります。Valve は、このサービスを非 Steam プレイヤーが常に利用できるという確約はできません。
ホストの識別と FakeIP
ネットワークホストがパブリック IP で識別されている場合(ほとんどのゲームサーバーに当てはまります)は、代わりに別の識別子を使用するように変更する必要があります。選べる識別子には、次のようなものがあります。
- Steam にサインインするゲームサーバーとクライアントの場合、通常は SteamID を使用します。
- ゲームサーバーが Steam にサインインせず、チケットベースの認証フローを使用している場合、意味のある他の識別子を使用できます。
SteamNetworkingIdentityのタイプで識別します。
一部のコードベースでは、ネットワークホストやゲームサーバーの識別に IPv4 アドレスを使用することが前提となっています。この場合、Steamworks の「Fake IP」システムを使用できます。FakeIP は、ほとんどの用途で有効な IPv4 アドレスのように「扱われる」IP で、インターネット上で使用されていない予約済みのアドレス空間から取得されます。FakeIP はルーティングできず、一般的なインターネット用途には使用できません(例:ping に応答しません)。チケットベースの認証を FakeIP システムと組み合わせて使用することは、現在はできません。
ISteamNetworkingSockets::BeginAsyncRequestFakeIP は、他のピアが P2P 経由で通信するために使用できるフェイクの IPv4 アドレスを割り当てる非同期プロセスを開始します。この関数によって返される IP アドレスは、指定された AppID に対してグローバルに一意です。すでにリクエストが進行中の場合は false を返し、新しいリクエストが開始された場合は true を返します。リクエストが完了すると、SteamNetworkingFakeIPResult_t がポストされます。ゲームサーバーの場合、この関数は、SDK を初期化してからログインを開始する前に必ず呼び出す必要があります。
UDP に近い方法で書かれたコードベースでは、パケットをいつでも任意のリモートホストにアドホックに送信できますが、すべてのメッセージが確立された「接続」に送信されるわけではありません。SteamID のような SteamNetworkingIdentity タイプを使用して識別されるホストとの通信には ISteamNetworkingMessages を使用し、FakeIP を使用して識別されるホストとの通信には ISteamNetworkingFakeUDPPort を使用します。
ロビー・サーバーとのつなぎ
ロビーとマッチメイキングの作り方にある Steam のロビーとマッチメイキングと使うと、パケットの種類に応じて、ホストとなる1人のプレイヤー(通常はロビーオーナー)またはゲームサーバーを通してすべてを通信するか、あるいは各プレイヤーにすべてを直接送信できます。Steam で選べる機能の全体はSteam で実装が要る仕様にあります。
クライアント-サーバーコミュニケーションにおける ISteamNetworkingSockets の使用例は、Steamworks API のサンプルアプリケーション(SpaceWar)にあります。
情報源
- Steamworks — Steamネットワーキング(API の種類と役目・Steam データグラムリレー・ISteamNetworking)https://partner.steamgames.com/doc/features/multiplayer/networking?l=japanese確認日 2026-10-21
- Steamworks — Steamデータグラムリレー(リレーの仕組み・ホストの識別・FakeIP・専用サーバーの接続の流れ)https://partner.steamgames.com/doc/features/multiplayer/steamdatagramrelay?l=japanese確認日 2026-10-21
- Steamworks — ISteamNetworkingSockets インターフェイス(接続の管理・メッセージの送受信・ポーリンググループ・FakeIP)https://partner.steamgames.com/doc/api/ISteamNetworkingSockets?l=japanese確認日 2026-10-21