Home

Awesome

WebRTC Signaling Server Ayame 仕様

概要

これは WebRTC P2P で利用するためのシグナリングサーバ向けの仕様です。 オープンソースとして公開されている https://github.com/OpenAyame/ayame はこの仕様に準拠して実装されています

注意

シグナリング

Ayame の ws://192.0.2.100:3000/signaling がクライアントからの WebSocket 接続を確立し、管理するエンドポイントとなります。

このエンドポイントに WebSocket で接続すると、Ayame は接続したクライアントの接続を保持します。

このシグナリングサーバは 1 対 1 専用のため、3 つ以上のクライアントの接続要求は拒否します。

Ayame は WebSocket で接続しているクライアントのうちどれかからデータが来ると、 送信元のクライアント以外の接続済みのクライアントにデータを そのまま WebSocket で送信します。これらはすべて非同期で行われます。

接続確立までのシーケンス図

                  +-------------+          +-------------------+         +-------------+                      +-----------------------+
                  |   client1   |          |      Ayame        |         |   client2   |                      | authentication server |
                  +-----+-------+          +--------+----------+         +------+------+                      +-----------+-----------+
                        |                           |                           |                                         |
                        |                           |                           |                                         |
                ============================= WebSocket 接続 =============================                                |
                        |                           |                           |                                         |
                        |GET /signaling             |                           |                                         |
                        |-------------------------->|                           |                                         |
                        |    101 Switching Protocols|                           |                                         |
                        |<--------------------------|                           |                                         |
                     +--|                           |             GET /signaling|                                         |
                     |  |                           |<--------------------------|                                         |
  Stream の取得      |  |                           |101 Switching Protocols    |                                         |
  PeerConnection の初期化等                         |-------------------------->|                                         |
                     |  |                           |                           |--+                                      |
                     |  |                           |                           |  |                                      |
                     |  |                           |                           |  | Stream の取得                        |
                     |  |                           |                           |  | PeerConnection の初期化等            |
                     |  |                           |                           |  |                                      |
         ============== ここからは WebSockets の Data フレームでの JSON の送受信 =================                        |
                     |  |                           |                           |  |                                      |
                ========================== クライアントの登録 =============================                               |
                     |  |{"type":"register",        |                           |  |                                      |
                     |  | "roomId": "...",          |                           |  |                                      |
                     |  | "clientId":"...",         |                           |  |                                      |
                     |  | "key":"...",              |                           |  |                                      |
                     |  | "authnMetadata": "..."}   |                           |  |                                      |
                     +->|                           |                           |  |                                      |
                        |-------------------------->|                           |  |                                      |
                        |                           |POST /ayame/webhook/authn  |  |                                      |
                        |                           |{"roomId":"...",           |  |                                      |
                        |                           | "clientId":"...",         |  |                                      |
                        |                           | "signalingKey":"...",     |  |                                      |
                        |                           | "authnMetadata":"..."}    |  |                                      |
                        |                           |-------------------------------------------------------------------->|
                        |                           |                           |  |                                      |--+
                        |                           |                           |  |               200 OK                 |  |
                        |                           |                           |  |               {"allowed":true,       |  | 認証処理
                        |                           |                           |  |                "iceServers":[],      |  |
                        |                           |                           |  |                "authzMetadata":"..."}|<-+
                        |                           |<--------------------------------------------------------------------|
                        |                           |                           |  |                                      |
  認証ウェブフックで    |   {"type":"accept",       |                           |  |                                      |
  認証拒否の場合は      |    "iceServers": [],      |                           |  |                                      |
  type は reject です   |    "isExistUser": false,  |                           |  |                                      |
                        |    "isExistClient": false,|                           |  |                                      |
                        |    "authzMetadata": "..."}|                           |  |                                      |
                        |<--------------------------|    {"type":"register",    |  |                                      |
  isExistClient が false の場合は、                 |     "roomId": "...",      |  |                                      |
  offer を送らずに相手クライアントの                |     "clientId":"...",     |  |                                      |
  登録を待ちます        |                           |     "key":"...",          |  |                                      |
                        |                           |     "authnMetadata":"..."}|<-+                                      |
                        |                           |<--------------------------|                                         |
                        |                           |POST /ayame/webhook/authn  |                                         |
                        |                           |{"roomId":"...",           |                                         |
                        |                           | "clientId":"...",         |                                         |
                        |                           | "signalingKey":"...",     |                                         |
                        |                           | "authnMetadata":"..."}    |                                         |
                        |                           |-------------------------------------------------------------------->|
                        |                           |                           |                                         |--+
                        |                           |                           |                  200 OK                 |  |
                        |                           |                           |                  {"allowed":true,       |  | 認証処理
                        |                           |                           |                   "iceServers":[],      |  |
                        |                           |                           |                   "authzMetadata":"..."}|<-+
                        |                           |<--------------------------------------------------------------------|
                        |                           |{"type":"accept",          |                                         |
                        |                           | "iceServers": [],         |                                         |
                        |                           | "isExistUser": true,      |                                         |
                        |                           | "isExistClient": true}    | isExistClient が true のため、          |
                        |                           |-------------------------->| offer を作成します                      |
                        |                           |                           |--+                                      |
                        |                           |                           |  |                                      |
                        |                           |                           |  | 作成した offer の SDP を             |
                        |                           |                           |  | setLocalDescription で               |
                        |                           |                           |  | PeerConnection に適用させます        |
                =================== SDP および ICE Candidate の交換 =======================                               |
                        |                           |           {"type":"offer",|  | offer を Ayame 経由で                |
                        |                           |            "sdp":"..."}   |<-+ 相手クライアントへ送ります           |
                        |                           |<--------------------------|                                         |
                        |           {"type":"offer",|                           |                                         |
                        |            "sdp":"..."}   |                           |                                         |
                        |<--------------------------|                           |                                         |
                     +--|                           |                           |                                         |
                     |  |                           |                           |                                         |
  受信した offer を  |  |                           |                           |                                         |
  setRemoteDescription で                           |                           |                                         |
  PeerConnection に適用させます                     |                           |                                         |
                     |  |                           |                           |                                         |
                     |  | {"type":"candidate",      |                           |                                         |
                     |  |  "ice":{"candidate":"..."}|                           |                                         |
                     |  |<--------------------------|                           |                                         |
  answer を作成します|  |                           |                           |                                         |
  作成した answer の SDP を                         |                           |                                         |
  PeerConnection に適用させます                     |                           |                                         |
  Answer を Ayame 経由で|                           |                           |                                         |
  相手クライアントへ送ります                        |                           |                                         |
                     |  |                           |                           |                                         |
                     +->|                           |                           |                                         |
                        |                           |                           |                                         |
                        |                           |{"type":"answer",          |                                         |
                        |                           | "sdp":"..."}              |                                         |
                        |                           |-------------------------->|                                         |
                        |                           |                           |                                         |
                        |                           |                           |                                         |
                  ======================== Trickle ICE の場合 ===========================                                 |
  ICE candidate イベント発火時に                    |                           |                                         |
  ICE candidate を Ayame 経由で                     |                           |                                         |
  相手クライアントへ送ります                        |                           |                                         |
                        |{"type":"candidate",       |                           |                                         |
                        | "ice":{"candidate":"..."} |                           |                                         |
                        |-------------------------->|                           |                                         |
                        |                           |                           |                                         |
                        |                           |{"type":"candidate",       |                                         |
                        |                           | "ice":{"candidate":"..."} |                                         |
                        |                           |-------------------------->|                                         |
                        |                           |                           | 受信した ICE candidate を               |
                        |                           |                           | addIceCandidate で                      |
                        |                           |                           | PeerConnection に追加します             |
                        |                           | {"type":"candidate",      |                                         |
                        |                           |  "ice":{"candidate":"..."}|                                         |
                        |                           |<--------------------------|                                         |
                        | {"type":"candidate",      |                           |                                         |
                        |  "ice":{"candidate":"..."}|                           |                                         |
                        |<--------------------------|                           |                                         |
                        |                           |                           |                                         |
                        |                           | {"type":"candidate",      |                                         |
                        |                           |  "ice":{"candidate":"..."}|                                         |
                        |                           |<--------------------------|                                         |
                        | {"type":"candidate",      |                           |                                         |
                        |  "ice":{"candidate":"..."}|                           |                                         |
                        |<--------------------------|                           |                                         |
                        |                           |                           |                                         |
                        |{"type":"candidate",       |                           |                                         |
                        | "ice":{"candidate":"..."} |                           |                                         |
                        |-------------------------->|                           |                                         |
                        |                           |                           |                                         |
                        |                           |{"type":"candidate",       |                                         |
                        |                           | "ice":{"candidate":"..."} |                                         |
                        |                           |-------------------------->|                                         |
                        |                           |                           |                                         |
                        |                           |                           |                                         |
                        |                           |                           |                                         |
                        |                           |                           |                                         |

プロトコル

WS のメッセージはJSONフォーマットでやり取りします。 すべてのメッセージはプロパティに type を持ちます。 type は以下の5つです。

type: register

クライアントが Ayame に対して roomId, clientId を登録するために利用するメッセージです。

{type: "register", "roomId" "<string>", "clientId": "<string>"}

Ayame は register メッセージを受け取ったら、 そのクライアントが指定した room に入室可能か検査して、可能であれば accept, 不可であれば reject を返却します。

もし認証ウェブフックが有効になっている場合は、まずは認証を行います。

type: accept

Ayame が register に込められている情報を検査し、 入室が可能であることをクライアントに知らせるメッセージです。

{type: "accept", isExistClient: "<boolean>"}

クライアントが accept を受け取った際、 isExistClient が true の場合は offer メッセージを送信します。 isExsistClient が false の場合は answer メッセージを待ちます。

type: reject

Ayame が register メッセージで指定した roomId に入室が 不可能 であることをクライアントに知らせるメッセージです。

{type: "reject", "reason": "<string>"}

これを受け取ったらクライアントは RTCPeerConnection や WebSocket を閉じて初期化する必要があります。

type: offer

accept を受け取り isExistClient: true を受け取ったクライアントは offer メッセージを Ayame に送信します。

{type: "offer", sdp: "v=0\r\no=- 4765067307885144980..."}

これを受け取ったクライアントはこの SDP を remoteDescription をセットします。 また、このタイミングで answer メッセージを生成し、localDescription にセットした後、anwser メッセージ を送信します。

type: answer

accept を受け取り isExistClient: false を受け取ったクライアントは offer メッセージを待ち、 offer メッセージを受け取ったら answer メッセージを送信します。

{type: "answer", sdp: "v=0\r\no=- 4765067307885144980..."}

type: candidate

ice candidate を交換するメッセージです。

{type: "candidate", ice: {candidate: "...."}}

これを受け取ったクライアントは ice candidate を追加します。

type: bye

シグナリング用の WebSocket を切断したことを知らせるメッセージです。

{type: "bye"}

これを受け取ったクライアントは RTCPeerConnection を閉じて、 リモート(受信側)の video element を破棄する必要があります。

シグナリング詳細

ウェブフック

認証サーバへ飛ばす情報

認証サーバから払い出す情報

シグナリング切断時に飛ばす情報

設定ファイル

ayame.conf

debug: true

log_dir: .
log_name: ayame.log
log_level: debug

signaling_log_name: signaling.log
webhook_log_name: webhook.log

listen_ipv4_address: 127.0.0.1
listen_port_number: 3000

# authn_webhook_url: http://127.0.0.1:3001/authn_webhook_url
# disconnect_webhook_url: http://127.0.0.1:3001/disconnect_webhook_url
# webhook_request_timeout: 5