見出し画像

Niantic Lightship ARDKのMultipeerNetworkingを使ってネットワーク機能を使用する方法

Niantic Lightship ARDK ネットワーク機能

Niantic Lightship ARDK ネットワーク機能は、セッション管理、ピアディスカバリ、メッセージルーティング、セッションベースのデータストアを提供する
サーバー(ARBE: AR BackEnd)によって支えられています。

セッション

セッションは、Niantic Lightship ARDK ネットワーク機能の基本的な概念です。クライアントが指定したセッション識別子で参加リクエストを送信すると、
サーバーは次のいずれかを行います。

セッションが存在しない場合
セッションを作成し、クライアントを「ホスト」として指定します。

セッションが存在する場合
クライアントをセッションに追加。

同じセッションに参加した後続のクライアントは、ホストの識別子を取得する事ができます。

using Niantic.ARDK.AR.Networking;
using Niantic.ARDK.Networking.MultipeerNetworkingEventArgs;
 
...
 
void CreateAndJoinNetworking()
{
  // MultipeerNetworkingをインスタンスを生成
  var networking = MultipeerNetworkingFactory.Create();
  // 接続した時のイベント登録 
  networking.Connected += OnNetworkingConnected;
  
  // セッション識別子
  string sampleSessionString = "jp.co.1planet.ardk.multipeer.sampleapp";
  var sessionIdFromString = Encoding.UTF8.GetBytes(sampleSessionString);
      
  // セッションに参加
  networking.Join(sessionIdFromString);
  return;
}
 
void OnNetworkingConnected(ConnectedArgs args)
{
  // セッションに参加できると、このイベントが呼び出される。
  Debug.LogFormat
  (
    "Connected to session with client ID: {0}, and host ID: {1}. Am I the host? {2}",
    args.Self.Identifier,
    args.Host.Identifier,
    args.IsHost
  );
}

セッション識別子の衝突

セッションは、最後のクライアントがセッションを離れてから30秒後にタイムアウトします。タイムアウト中にクライアントがセッションに参加した場合、意図しない動作を引き起こす可能性があります。

このようなことがないよう一意性のセッション識別子を使用することを推奨しています。(セッション識別子にプレフィックスまたはサフィックスにドメインやアプリケーション名などを付けるようにした方が良いでしょう。)

ピア

ピアは、セッションに参加したクライアントを表現したものです。
接続後、数秒以内にクライアントはIMultipeerNetworking.PeerAdded(PeerAddedArgs args) イベントを通じて、すでにセッションに参加しているピアの情報にアクセスすることができます。

セッションに現在参加しているすべてのピア(ローカル クライアントを除く)は、IMultipeerNetworking.OtherPeers に格納されています。

ピアがセッションから離れると、IMultipeerNetworking.PeerRemoved(PeerRemovedArgs args) のイベントが発生します。ローカルクライアントが参加する前にセッションに参加して、離脱したピアの情報にアクセスすることはできません。

void SubscribeToPeerAddedRemoved(IMultipeerNetworking networking)
{
  networking.PeerAdded += OnPeerAdded;
  networking.PeerRemoved += OnPeerRemoved;
}
 
void OnPeerAdded(PeerAddedArgs args)
{
  Debug.LogFormat("Peer joined: {0}", args.Peer.Identifier);
}
 
void OnPeerRemoved(PeerRemovedArgs args)
{
  Debug.LogFormat("Peer left: {0}", args.Peer.Identifier);
}

メッセージ

ネットワーク・ロジックの大部分は、メッセージの送受信が中心で、アクションやゲーム・ステートの変更をピアに知らせたり、アニメーションを同期させたりします。ネットワーク・メッセージは、uintタグとbyte配列のメッセージで構成されています。

タグは、データの分類を表す時などに使用します。
例えば、Pongというゲームでは以下のような分類が考えられます。

1というタグにローカル・プレー ヤーのポジション情報(Vector3)。
2というタグにのスコア情報(int)。

メッセージの送信

メッセージを送信するためのAPIがいくつかあり、メッセージの送信に使用するトランスポートプロトコルのオプションも用意されています。

ここでは、さまざまなプロトコルのピアにメッセージを送信する3つの例を紹介します。

// セッション内の1つのピアに送信されるメッセージ。
void SendToASinglePeer(IMultipeerNetworking networking, IPeer peer, byte[] data)
{
  networking.SendDataToPeer(tag: 0, data: data, peer: peer, transportType: TransportType.UnreliableUnordered);
}
 
// 送信したクライアントとホストを除くセッション内のすべてのピアにデータを送信する。
void SendToAllPeersButHost(IMultipeerNetworking networking, byte[] data)
{
  // セッションに参加している他のすべてのピアのリストを生成する。
  var peerListCopy = networking.OtherPeers.ToList();
 
  // リストからホストを削除する
  peerListCopy.Remove(networking.Host);
 
  networking.SendDataToPeers(tag: 1, data: data, peers: peerListCopy, transportType: TransportType.ReliableOrdered);
}
 
// ホストと送信したクライアントも含めた全ピアにデータを送信する。
void BroadCastToSession(IMultipeerNetworking networking, byte[] data)
{
  // sendToSelfのフラグを立てると送信したクライアントにも送信されます。
  networking.BroadcastData(tag: 2, data: data, transportType: TransportType.UnreliableOrdered, sendToSelf: true);
}

メッセージの受信

メッセージが送信されると、受信側のピアは IMultipeerNetworking.PeerDataReceived(PeerDataReceivedArgs args) イベントでメッセージを受信することになります。

void SubscribeToPeerDataReceived(IMultipeerNetworking networking)
{
  networking.PeerDataReceived += OnPeerDataReceived;
}
 

void OnPeerDataReceived(PeerDataReceivedArgs args)
{

  Debug.LogFormat
  (
    "Received a message from {0}, with tag {1} and length {2}",
    args.Peer,
    args.Tag,
    args.DataLength
  );
 
  MemoryStream data = args.CreateDataReader();
  
}

トランスポートの種類

メッセージの送信に使用する4種類のトランスポートがあります。

UnreliableUnordered
UnreliableOrdered
ReliableUnordered
ReliableOrdered

メッセージ送信時のトランスポートによって、xxx(あるいはメッセージを受信しない可能性もある)。

Unreliable
メッセージの受信を必ずしも保証しません。(送信したデータが受信しない可能性があります。)メリットはメッセージ送信時のオーバーヘッドが発生しないため、連続したデータを送信するケース(アバターの現在位置や動画の1フレームなど)、全てのデータが受信する必要でない一時的なデータに向いています。

Reliable
メッセージの受信は保証されます。メッセージ受信を保証するためメッセージの再送信やメッセージの回復に試みるためオーバーヘッドが発生します。

Unordered
送信したメッセージは順序に従って、メッセージが受信することを保証しない。

Ordered
送信したメッセージは順序に従って、メッセージが受信することを保証する。

参考

最後に

OnePlanet XR

OnePlanet XR はAR/MR技術に専門特化したコンサルティングサービスです。豊富な実績を元に、AR/MR技術を活用した新たな事業の立ち上げ支援や、社内業務のデジタル化/DX推進など、貴社の必要とするイノベーションを実現いたします。
ご相談から受け付けております。ご興味ございましたら弊社までお問い合わせください。(以下にアクセスするとお問い合わせページに遷移されます。)

https://1planet.co.jp/xrconsulting.html

Niantic Lightship ARDK のブログ記事

この記事以外にNiantic Lightship ARDKのブログ記事を投稿しています。

OnePlanet Tech Magazine

Niantic Lightship ARDK以外のAR技術記事も定期的に投稿してます。