3

私が開発している iOS アプリでは、複数の電話を相互に接続し、それらのデバイス間で音声チャットできるようにしたいと考えています。

両方のデバイスが同じネットワーク上にある場合に機能します。これは非常に簡単で、私がやりたいことのほとんどは可能です。

しかし今、私はインターネットサポートを追加していますが、これはかなり面倒です. 最初に、セットアップした小さな Web サービスを使用して、デバイスを一致させる方法を説明します。

サーバ

  1. セッションモードの GKSessionModePeer を使用して、新しい GameKit セッションを開始します
  2. 作成したばかりのセッションでサーバーの「ピア ID」を見つけます
  3. 空いているポートに新しい CFSocketRef を作成し、接続を受け入れる準備を整えます
  4. 外部サーバーで実行されている Web サービスにピア ID とポート番号を送信します。

ウェブサービス

  1. Webservice はその情報を受け取り、クライアントの ID と IP アドレスとともにデータベースに格納します。
  2. ID をサーバーに送り返すと、ID が表示されます

クライアント

  1. ユーザーが GameKit の「オンライン」機能を使用してゲームを検索することを選択した場合、ユーザーに ID (サーバーが受け取る ID を入力する必要があります) を尋ねます。
  2. クライアントは、ID を提供する Web サービスに接続します。Web サービスは、サーバーのセッション (IP、ポート、ピア ID) に関する情報を返します。
  3. ユーザーは、ポート情報を使用して IP アドレスに接続し、サーバーとの入出力ストリームを設定しようとします。

私のネットワークは(外部ネットワークからの)着信接続とランダムポートを許可していないため、これはもちろん機能しません。

しかし今問題は、これをどのように解決するかです。2 つのデバイス間でピアツーピア接続をセットアップできるようにしたいのですが、これらのデバイスは同じネットワーク上にある可能性がありますが、別のネットワーク上にある可能性もあります。

これを行う方法を示すフレームワーク、例、または何かがありますか? 最初にサーバーに送信せずに、デバイスからデバイスにデータを送信できるようにしたいと考えています。

4

1 に答える 1

6

これを行うフレームワークは知りません。ただし、複数のネットワークにまたがる p2p ネットワーキングの経験は豊富です。

私が学んだ重要なルールの 1 つは、ネットワーク間で通信するときは、必要でない限り直接接続を作成しないことです。ファイアウォール、NAT など、問題を引き起こす可能性がある (発生する?) 要因が多すぎます。

もちろん、最初に接続を試すことができます。指定された IP アドレスに接続を試みることができます*が、ほとんどの場合失敗します。UPnP と NAT-PMP を使用している場合でも、多くの場合 (半分以上?) 着信接続をまったく受け入れることができないことがわかります。

そのため、必ずバックアップ計画を立ててください。だけlisten()でなく、サーバーにも接続するネットワーク層の抽象化を行います。そうすれば、クライアントの IP* に接続できない場合でも、サーバー経由で接続をセットアップするだけで、ネットワークの抽象化によってすべて処理されます。

上記のことを繰り返します。受信接続だけに頼るのではなく、常にバックアップ計画を立ててください。


* クライアントは複数のローカル/リモート IP を持つことができるため、IP を書きます。接続するときは、常にこれらすべての IP を反復処理します。例: 私の電話には 2 つのローカル IPv4 アドレス (10.0.0.172 と 10.8.0.2) と IPv6 アドレス ([2001:x:x::6]) があります。これら 3 つのアドレスのうち、パブリックに到達できるのは IPv6 アドレスのみであり、2 つの IPv4 アドレスは異なるサブネット上にあるため、それらに接続できるかどうかは、他のクライアントが存在するサブネットに依存します。常に両方への接続を試み、失敗した場合はサーバー プロキシ接続にフォールバックします。

** IPv6 について言及しました。はい。IPv4 とは異なり、IPv6 は NAT によって制限されないことを忘れないでください。これは、サポートされている場合、IPv4 よりも IPv6 経由で良好な接続を得る可能性がはるかに高いことを意味します。

于 2012-12-22T18:50:24.517 に答える