0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

WebRTCについて調べる

Posted at

WebRTCの技術について調べ、SkyWayを触ってみる。

WebRTCとは

「Web Real-Time Communication」の略称。WebRTCはビデオ会議などリアルタイムでの通信を実現する仕組み。

用語

  • シグナリングサーバ
    通信相手に関する情報を得る役割のサーバ。

  • P2P
    「Peer to Pee」の略。サーバーを介さず、端末同士が直接通信できるようにする。

  • NAT
    ネットワークアドレスを変換する機能。インターネットにつながっているIPアドレスを複数の端末で利用する方法。
    ファイアウォールの機能の一部。

  • NAT越え
    NATによってプライベートIPアドレスに外部から直接アクセスすることはできない(グローバルIPを介する必要がある)。「NAT越え」技術を活用すると、プライベートIPアドレスしか持たないデバイス同士を、インターネットを通じて通信することが可能になる。
    ①STUNサーバーから情報を得る
    →②シグナリングサーバ経由で通信相手に情報を渡す
    →③得た情報によりポートをマッピングし、直接P2P通信を行う

    • STUNサーバ
      「Session Traversal Utilities for NATs」
      NATで割り当てられたグローバルIPアドレスとポート番号の情報を、NATの外側に用意されたSTUNサーバから返すため、ブラウザがローカルネット内で外から見た情報(グローバルIPアドレスとポート番号)を知ることができる。
      ここで得た情報をシグナリングサーバー経由で通信相手に渡す。
      STUNでNATを越えられないときはTURNを使う。
  • ファイアウォール越え
    Firewallが設置されているケースでは外部と通信できるポートも制限され、STUNサーバーを使用しても通信を行うことができない。P2Pに代わって、TURNサーバが通信を仲介(リレー)することで通信を可能にする。

    • TURNサーバ
      「Traversal Using Relay around NAT」
      NATの外側にデータをリレーする。端末同士は直接通信せずに、リレーサーバ経由で通信する。P2P通信ではなくなるためネットワーク負荷が高くなりやすい。

    • ICE
      「Interactive Connectivity Establishment」 
      STUN」および「TURN」の2つの技術を組み合わせてNAT越えを行う。

  • SFUサーバ
    「Selective Forwarding Unit」
    多人数通話や映像配信を実現する。3人以上で通信する際に端末のエンコード負荷と上り帯域幅や通信量を削減できるため、Mesh方式(※)より多人数での通信が可能になる。

Skywayについて

WebRTCに必要な4つのサーバをAPI経由で利用可能にするSDK。

  • シグナリングサーバ
  • STUNサーバ
  • TURNサーバ
  • SFUサーバ
1) シグナリングサーバと接続する

new Peerを実行

// デバッグ情報を最大(3)にして接続する場合
const peer = new Peer('some-peer-name', {
  key:   "<YOUR-API-KEY>"
  debug: 3,
});

// TURNサーバを強制利用する場合
const peer = new Peer({
  key:   "<YOUR-API-KEY>"
  config: {
    iceTransportPolicy: 'relay',
  },
});
  • 対象のサーバをディスパッチャーサーバに問い合わせる
  • 認証サーバの認証情報の検証
  • PeerIDの生成
  • TURNサーバ接続用の認証情報取得
  • 定期的にping/pongを実施
  • openイベントが発火
2) 1対1の発信処理(callメソッド)

指定した Peer にメディアチャネル(音声・映像)で接続して、MediaConnectionを作成。

// 自身のlocalStreamを設定して、相手に発信する場合
const MediaConnection = peer.call("peerID", localStream);

// 自身のlocalStreamおよびmetadataを設定して、相手に発信する場合
const MediaConnection = peer.call("peerID", localStream, {
  metadata: {
    foo: "bar",
  },
});

// 映像コーデックとしてH264を利用する場合
const MediaConnection = peer.call("peerID", localStream, {
  videoCodec: "H264",
});

// 音声のみ接続先から受信する設定で、相手に発信する場合
const MediaConnection = peer.call("peerID", null, {
  audioReceiveEnabled: true,
});
2) データの送信(connectメソッド)

指定した Peer にデータチャネルで接続して、DataConnectionインスタンスを生成する。

// 単にDataChannelを接続する場合(デフォルトで信頼性有り)
const DataConnection = peer.connect("peerId");

// metadata付きでconnectする場合
const DataConnection = peer.connect("peerId", {
  metadata: {
    hoge: "foobar",
  },
});

3) ルームに参加する(joinRoomメソッド)

メッシュ接続のルーム、または SFU 接続のルームに参加する。

// Mesh接続を利用する場合
const room = peer.joinRoom("roomName", {
  mode: "mesh",
  stream: localStream,
});

// SFU接続を利用する場合
const room = peer.joinRoom("roomName", {
  mode: "sfu",
  stream: localStream,
});

// ルームが接続されたときに発生
room.on("open", () => {});

// ルーム内に存在する各Peerとの間のRTCPeerConnectionを取得(キーがpeerId、値がRTCPeerConnectionのオブジェクト)
const pcs = room.getPeerConnections();

// ルームに新しい Peer が参加したときに発生
room.on("peerJoin", (peerId) => {
  // ...
});

// 新規に Peer がルームを退出したときに発生
room.on("peerLeave", (peerId) => {
  // ...
});

// データを送信
room.send(data);

// 更新
room.replaceStream(stream)

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?