# WebSocket 経由のシグナリング

## 概要

> **重要**
>
> Sora の SDK を利用する場合は、ここに書かれているシグナリングの細かい仕様を把握する必要は基本的にありません。

Sora のシグナリングにはデフォルトでは WebSocket を使用します。

## 用語


### channel_id

接続のグルーピングに利用する ID です。
接続時に任意の文字列、最大 255 バイトまでを自由に指定できます。


### session_id

channel_id への接続が 0 から 1 に切り替わったタイミングで生成される id です。
1 から 0 になり、一定期間が経過したタイミングでセッションは破棄されます。

セッションが破棄された後、
再度同一 channel_id で接続が 0 から 1 になった場合、新しい session_id が生成されます。

セッションごとのユニークな値です。
UUIDv4 で生成した値を Base32 でエンコードした値で、Sora が払い出します。指定はできません。


### client_id

接続時やサーバー認証成功時に任意の文字列を最大 255 バイトまで指定できる値です。
指定しない場合は connection_id が入ります。自由に指定できます。重複が可能な ID です。

> **注釈**
>
> `sora.conf` の [default_duplicate_client_id](SORA_CONF.html#c8b57b) を `evict` 、
> または [session.created](SESSION_WEBHOOK.html#1d1984) の払い出しに `duplicate_client_id` を `evict` に指定した場合はセッション単位でクライアント ID が重複するクライアントが接続してきた場合、
> 最初に接続していたクライアントが追い出されます。


### bundle_id

`bundle_id` を指定した場合、マルチストリーム利用時に `bundle_id` が等しい接続からの音声や映像、メッセージング、シグナリング通知を受信しなくなります。

接続時やサーバー認証成功時に任意の文字列を最大 255 バイトまで指定できる値です。指定しない場合は connection_id が入ります。

シグナリングでの bundle_id の指定はデフォルトでは無効になっているため、有効にする場合には `sora.conf` にて `signaling_bundle_id` を `true` にする必要があります。


### connection_id

接続ごとのユニークな値です。
UUIDv4 で生成した値を Base32 でエンコードした値で、Sora が払い出します。指定はできません。

**connection_id の例**
: "FW0CJSHETX0RXAGX8WWEXNBQN8"

## 仕組み

Sora のシグナリングは、Sora からクライアントへ Offer (SDP) を送ります。

シグナリングの処理の流れは、[認証ウェブフックなし](WEBSOCKET_SIGNALING.html#cea9ce) のシーケンス図をご確認ください。

シグナリングの型の正確な仕様は [シグナリングの型定義](SIGNALING_TYPE.html) をご確認ください。

### URL

デフォルトの設定では、シグナリングは `0.0.0.0:5000` でリッスンするため、
シグナリング URL は `http://<サーバーのアドレス>:5000/signaling` となります。

**パス部分は /signaling 固定で変更できません** 。

### DataChannel 経由への切り替え

詳細は [DataChannel 経由のシグナリング](DATA_CHANNEL_SIGNALING.html) をご確認ください。

## 注意

シグナリングが完了しても WebSocket の接続は切断しないでください。WebSocket の接続が切れると Sora は WebRTC 接続を終了します。

- 30 秒以内に `"type": "answer"` を受信しなかった場合、 Sora は接続を終了します
- 30 秒以内に `"type": "re-answer"` を受信しなかった場合、 Sora は接続を終了します

## 設定


### signaling_loopback_address_only

`sora.conf` にて [signaling_loopback_address_only](WEBSOCKET_SIGNALING.html#e22105) を `true` にすることで、
ループバックアドレスからのみアクセスできるようにします。

NGINX などを前段に利用している場合は可能な限り有効にしてください。

## シグナリングのタイプ

Sora のシグナリングは、タイプごとの JSON でクライアントとメッセージをやりとりします。

### "type": "connect"

クライアントは Sora に接続の意思を伝える JSON を送ります。以下は最小の JSON です。

```javascript
{
  "type": "connect",
  "role": "sendonly",
  "channel_id": "Spam"
}
```

#### role

そのクライアントの役割を指定します。この設定は必須です。

`role` には `sendrecv` / `sendonly` / `recvonly` のどれかを指定してください。

- sendrecv- 送信及び受信を行います
- sendonly- 送信のみを行い、受信を行いません
- recvonly- 受信のみを行い、送信を行いません

#### channel_id

`channel_id` は 1-255 バイトまでの文字列であればどのような文字列でも指定できます。


#### 配信または視聴メディアの選択

**この項目はオプションです**

`audio` と `video` を指定することにより配信、または視聴するメディアを選択することができます。 `role` に `sendrecv` または `sendonly` を指定した場合は配信するメディア、 `recvonly` を指定したときは視聴するメディアについての指定となります。

この設定が未指定の場合は、 `true` がデフォルトで指定され、映像と音声両方の配信、または映像と音声両方の受信が行われます。

以下の例では `role` に `sendrecv` が指定されており、音声のみが配信されます。

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "Spam",
    "video": false
}
```

> **注釈**
>
> `role` に `sendrecv` が指定された場合は常に映像と音声両方を受信します。
> もし特定のストリームを受信したくないなどある場合は [転送フィルター機能](FORWARDING_FILTER.html) を利用してください。

以下の例では `role` に `sendonly` が指定されており、映像のみが配信されます。

```javascript
{
    "type": "connect",
    "role": "sendonly",
    "channel_id": "Spam",
    "audio": false
}
```

以下の例では `role` に `recvonly` が指定されており、音声のみが受信されます。

```javascript
{
    "type": "connect",
    "role": "recvonly",
    "channel_id": "Spam",
    "video": false
}
```

#### オーディオコーデック指定

**この項目はオプションです**

`role` が `sendrecv` または `sendonly` の場合はオーディオコーデックを指定できます。

この設定はオプションです。

この設定が指定されない場合は、 `OPUS` がデフォルトで設定されます。

- Opus- "OPUS"

```javascript
{
  "type": "connect",
  "role": "sendonly",
  "channel_id": "Spam",
  "audio": {
    "codec_type":"OPUS"
  }
}
```

#### オーディオビットレート指定

**この項目はオプションです**

> **重要**
>
> オーディオビットレートは指定しないことをおすすめします。指定しないことで最適なビットレートが採用されます。

`role` が `sendrecv` または `sendonly` の場合はオーディオビットレートの最大値を指定できます。

このビットレート指定は Opus にのみ有効です。

- bit_rate- 6-510

```javascript
{
  "type": "connect",
  "role": "sendonly",
  "channel_id": "Spam",
  "audio": {
    "codec_type": "OPUS",
    "bit_rate": 64
  }
}
```

指定できる値は 6 から 510 です。32 を指定した場合は、32kbps がビットレートの最大値です。

指定しない場合は `sora.conf` の `default_audio_bit_rate` に指定した値が採用されます。
`default_audio_bit_rate` も指定していない場合、ビットレートはクライアント側に依存します。


#### オーディオの Opus 設定指定

> **注意**
>
> この機能は実験的機能です。この機能を利用される場合は必ず事前にサポートまでご連絡ください

`role` が `sendrecv` または `sendonly` の場合は Opus の設定を指定できます。

- opus_params- channels- 1-8
  - maxplaybackrate- 8000-48000
  - stereo- boolean
  - sprop_stereo- boolean
  - minptime- integer 3-120
  - useinbandfec- boolean
  - usedtx- boolean
    - **この機能を有効にした場合は録画がおかしくなります**

```javascript
{
  "type": "connect",
  "role": "sendonly",
  "channel_id": "Spam",
  "audio": {
    "codec_type": "OPUS",
    "opus_params": {
      "stereo": false,
      "useinbandfec": false
    }
  }
}
```

#### ビデオコーデック指定

**この項目はオプションです**

`role` が `sendrecv` または `sendonly` の場合はビデオコーデックを指定できます。

この設定はオプションです。

この設定が指定されない場合は、VP9 がデフォルトで設定されます。

- VP8- `"VP8"`
- VP9- "`VP9"`
- AV1- `"AV1"`
  - Chrome M96 以降で利用できます
  - Safari では機能フラグを有効にすることで利用できます
  - Sora SDK で利用できます
- H.264- `"H264"`
- H.265- `"H265"`
  - Chrome M137 以降で利用できます
  - Safari で利用できます
  - Sora SDK で利用できます

```javascript
{
  "type": "connect",
  "role": "sendonly",
  "channel_id": "Spam",
  "video": {
    "codec_type":"VP9"
  }
}
```

#### ビデオビットレート指定

**この項目はオプションです**

`role` が `sendrecv` または `sendonly` の場合はビデオビットレートの最大値を指定できます。単位は **kbps** です。

- bit_rate- 1-50000

```javascript
{
  "type": "connect",
  "role": "sendonly",
  "channel_id": "Spam",
  "video": {
    "codec_type": "VP9",
    "bit_rate": 500
  }
}
```

指定できる値は 1 から 50000 です。500 を指定した場合は、500 kbps がビットレートの最大値です。

10 Mbps を最大値としたい場合は 10000 を指定してください。ただし 15 Mbps より大きい値は現時点ではサポート外となります。

指定しない場合は `sora.conf` の `default_video_bit_rate` に指定した値が採用されます。


#### ビデオの VP9 設定指定

`role` が `sendrecv` または `sendonly` の場合は VP9 のプロファイル ID を指定できます。
VP9 のプロファイル ID を指定をする場合は、あわせて `codec_type` に `VP9` を指定する必要があります。

- vp9_params- profile_id- integer
    - 0-3

この値を指定するには `sora.conf` にて [signaling_vp9_params](SORA_CONF.html#3261ea) を `true` に設定する必要があります。

```javascript
{
  "type": "connect",
  "role": "sendonly",
  "channel_id": "Spam",
  "video": {
    "codec_type": "VP9",
    "vp9_params": {
      "profile_id": 2
    }
  }
}
```


#### ビデオの AV1 設定指定

`role` が `sendrecv` または `sendonly` の場合は AV1 のプロファイル を指定できます。
AV1 のプロファイル を指定をする場合は、あわせて `codec_type` に `AV1` を指定する必要があります。

- av1_params- profile- integer
    - 0-2
  - level_idx- integer
    - 0-31
  - tier- integer
    - 0-1

この値を指定するには `sora.conf` にて [signaling_av1_params](SORA_CONF.html#91f3b8) を `true` に設定する必要があります。

```javascript
{
  "type": "connect",
  "role": "sendonly",
  "channel_id": "Spam",
  "video": {
    "codec_type": "AV1",
    "av1_params": {
      "profile": 0,
      "level_idx": 5,
      "tier": 0
    }
  }
}
```


#### ビデオの H.264 設定指定

`role` が `sendrecv` または `sendonly` の場合は H.264 のプロファイルレベル ID を指定できます。
H.264 のプロファイルレベル ID を指定をする場合は、あわせて `codec_type` に `H264` を指定する必要があります。

- h264_params- profile_level_id- string
    - "42e02a" など
  - b_frame- boolean
    - `sora.conf` にて [h264_b_frame](SORA_CONF.html#f546aa) が `true` に指定されているときに指定できます

この値を指定するには `sora.conf` にて [signaling_h264_params](SORA_CONF.html#b32e49) を `true` に設定する必要があります。

```javascript
{
    "type": "connect",
    "role": "sendonly",
    "channel_id": "Spam",
    "video": {
        "codec_type": "H264",
        "h264_params": {
            "profile_level_id": "42e02a"
        }
    }
}
```


#### ビデオの H.265 設定指定

> **注意**
>
> この機能は実験的機能です。この機能を本番環境で利用される場合は必ず事前にサポートまでご連絡ください

> **警告**
>
> この機能はまだ対応しているライブラリが存在しません。

`role` が `sendrecv` または `sendonly` の場合は H.265 のプロファイルレベル ID を指定できます。
H.265 のプロファイルレベル ID を指定をする場合は、あわせて `codec_type` に `H265` を指定する必要があります。

- h265_params- level_id- integer
    - 93 など
  - profile_id- integer
    - 0-31
  - tier_flag- integer
    - 0-1
  - tx_mode- string
    - "SRST" または "MRST" または "MRMT"
  - b_frame- boolean
    - `sora.conf` にて [h265_b_frame](SORA_CONF.html#a9a8f8) が `true` に指定されているときに指定できます

この値を指定するには `sora.conf` にて [signaling_h265_params](SORA_CONF.html#8ed4e9) を `true` に設定する必要があります。

```javascript
{
    "type": "connect",
    "role": "sendonly",
    "channel_id": "Spam",
    "video": {
        "codec_type": "H265",
        "h265_params": {
            "level_id": 93,
            "profile_id": 1,
            "tier_flag": 0,
            "tx_mode": "SRST"
        }
    }
}
```

#### 認証メタデータ

**この項目はオプションです**

認証するための判断材料としてメタデータを使用できます。

認証メタデータは必須ではありません。

```javascript
{
    "type": "connect",
    "role": "sendonly",
    "channel_id": "Spam",
    "metadata": "1234abcd"
}
```

認証メタデータは、そのまま認証サーバーに送られます。詳細は [認証ウェブフック](AUTH_WEBHOOK.html) をご確認ください。


#### client_id の指定

**この項目はオプションです**

> **重要**
>
> `client_id` の値は重複することができます。

1-255 バイトまでの文字列であれば、どのような文字列でも指定できます。

```javascript
{
    "type": "connect",
    "role": "sendonly",
    "channel_id": "Spam",
    "client_id": "egg-ham"
}
```


#### bundle_id の指定

**この項目はオプションです**

> **重要**
>
> `bundle_id` の値は重複することができます。

1-255 バイトまでの文字列であれば、どのような文字列でも指定できます。

マルチストリーム利用時に `bundle_id` が同じ接続からの音声や映像、メッセージングを受信しなくなります。

この値を指定するには `sora.conf` にて [signaling_bundle_id](SORA_CONF.html#279311) を `true` に設定する必要があります。

```javascript
{
    "type": "connect",
    "role": "sendonly",
    "channel_id": "Spam",
    "bundle_id": "spam_egg"
}
```

#### サイマルキャスト

**この項目はオプションです**

自分が配信する映像のストリームを複数本にすることで、
受信側にどのストリームを受信するかを選択させることができるようになります。

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "spam",
    "simulcast": true
}
```

詳細は [サイマルキャスト機能](SIMULCAST.html) をご確認ください。

#### サイマルキャストマルチコーデック

**この項目はオプションです**

自分が配信する映像のストリームを複数本かつ、複数コーデックにすることができます。

サイマルキャストマルチコーデック機能を利用する場合、
`sora.conf` にて [simulcast_multicodec](SORA_CONF.html#a8cf0f) を `true` に設定する必要があります。

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "spam",
    "simulcast": true,
    "simulcast_multicodec": true
}
```

詳細は [サイマルキャストマルチコーデック機能](SIMULCAST_MULTICODEC.html) をご確認ください。

#### スポットライト

**この項目はオプションです**

話をした人にフォーカスを当てて、フォーカスが当たっている人は高画質な映像と音声で配信、
フォーカスが当たっていない人は低画質な映像で配信するという、クライアントの負荷を下げる仕組みです。

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "spam",
    "simulcast": true,
    "spotlight": true
}
```

詳細は [スポットライト機能](SPOTLIGHT.html) をご確認ください。

#### 転送フィルター

**この項目はオプションです**

接続時に転送フィルターを指定することで、条件に該当する他のチャネル参加者の音声や映像の受信をブロックする仕組みです。

- forwarding_filters- 受信をブロックする条件をリストで指定します
  - 接続後は [転送フィルター API](API_FORWARDING_FILTER.html) を利用してフィルターの変更、削除ができます
  - この機能を利用するには [signaling_forwarding_filters](SORA_CONF.html#bf0e30) を `true` に設定する必要があります

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "spam",
    "forwarding_filters": [
      {
        "action": "block",
        "rules": [
            [
            {"field": "kind", "operator": "is_in", "values": ["audio"]}
            ]
        ]
      }
    ]
}
```

詳細は [転送フィルター機能](FORWARDING_FILTER.html) をご確認ください。

#### sdp

**この項目はオプションです**

Sora SDK や Sora クライアントで生成した offer SDP を Sora のログに記録します。
この項目は、ログの記録にのみ利用します。

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "spam",
    "sdp": "..."
}
```

#### sora_client

**この項目はオプションです**

Sora SDK や Sora クライアントの情報を文字列で送ることができます。
これはログに記録されたり、認証ウェブフックリクエストで送信されたりします。

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "sora",
    "sora_client": "Sora JavaScript SDK 2021.1.0"
}
```

#### environment

**この項目はオプションです**

Sora SDK や Sora クライアントの利用環境を文字列で送ることができます。
これはログに記録されたり、認証ウェブフックリクエストで送信されたりします。

Sora JavaScript SDK では userAgent の情報が入ります。

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "sora",
    "environment": "Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/93.0.4522.0 Safari\/537.36"
}
```

#### libwebrtc

**この項目はオプションです**

Sora SDK や Sora クライアントの libwebrtc のバージョンを文字列で送ることができます。
これはログに記録されたり、認証ウェブフックリクエストで送信されたりします。

```javascript
{
    "type": "connect",
    "role": "sendrecv",
    "channel_id": "sora",
    "libwebrtc": "Shiguredo-Build M90.4430@{#3} (90.4430.3.1 dee77cf2)"
}
```

#### redirect

クラスター利用時に、接続先の Sora から `"type": "redirect"` を受け取って、
再度 Sora へ接続する際に、この値に `true` を指定する必要があります。

### "type": "offer"

認証ウェブフックが認証成功を返すと、Sora は以下のような JSON をクライアントに送ります。
SDK を利用している場合は、この仕様を意識する必要はありません。

```javascript
{
    "type": "offer",
    "sdp": "<SDP>",
    "channel_id": "sora",
    "session_id": "05JTBDGM1H3GB7FK0B1CJ45JE0",
    "connection_id": "ECF3W1RGMD02DETH30CDZTHNRW",
    "client_id": "ECF3W1RGMD02DETH30CDZTHNRW",
    "bundle_id": "ECF3W1RGMD02DETH30CDZTHNRW",
    "simulcast": false,
    "spotlight": false,
    "version": "2024.2.0",
    "metadata": "1234abcd",
    "audio": true,
    "audio_codec_type": "OPUS",
    "video": true,
    "video_codec_type": "VP9",
    "video_bit_rate": 500,
    "config": {
      "iceServers": [
        {
          "credential": "ClDTPB4DjgFLrclpSBxjTiXg7K8kYsGf",
          "urls": [
            "turn:192.0.2.1:443?transport=tcp"
          ],
          "username": "sYL5WdMt"
        }
      ],
      "iceTransportPolicy": "relay"
    },
    "mid": {
        "audio": "audio_aDScYe",
        "video": "video_i2sNRq"
    },
    "data_channels": [
      {
        "compress": true,
        "label": "stats",
        "ordered": true,
        "direction": "sendrecv"
      },
      {
        "compress": true,
        "label": "push",
        "ordered": true,
        "direction": "recvonly"
      },
      {
        "compress": true,
        "label": "notify",
        "ordered": true,
        "direction": "recvonly"
      },
      {
        "compress": true,
        "label": "signaling",
        "ordered": true,
        "direction": "sendrecv"
      },
      {
        "compress": true,
        "label": "rpc",
        "ordered": true,
        "direction": "sendrecv"
      }
    ],
    "rpc_methods": [
      "2025.2.0/PutSignalingNotifyMetadata",
      "2025.2.0/PutSignalingNotifyMetadataItem"
    ]
}
```

- channel_id- `"type": "connect"` の `channel_id` で指定した値が入ります
- session_id- UUIDv4 を Base32 でエンコードしたユニークな ID が入ります
- connection_id- UUIDv4 を Base32 でエンコードしたユニークな ID が入ります
- client_id- クライアントや認証サーバーが指定した値、または、Sora が生成した connection_id が入ります
- bundle_id- クライアントや認証サーバーが指定した値、または、Sora が生成した connection_id が入ります
- config- RTCPeerConnection に渡す設定が入ります
  - 主に TURN の情報です
- mid- audio と video の MediaStream Id が入ります
- audio- 音声の配信を行うかどうかが入ります
- audio_codec_type- これはオプションです
  - `audio` が `true` かつ `role` が `sendrecv` または `sendonly` の場合に含まれます
  - 音声のコーデックが入ります
- audio_bit_rate- これはオプションです
  - `audio` が `true` かつ `role` が `sendrecv` または `sendonly` で `audio_bit_rate` が指定された場合に含まれます
  - 音声のビットレートが入ります
- video- 映像の配信を行うかどうかが入ります
- video_codec_type- これはオプションです
  - `video` が `true` かつ `role` が `sendrecv` または `sendonly` の場合に含まれます
  - 映像のコーデックが入ります
- video_bit_rate- これはオプションです
  - `video` が `true` かつ `role` が `sendrecv` または `sendonly` の場合に含まれます
  - 映像のビットレートが入ります
- version- Sora のバージョンが入ります
- metadata- これはオプションです
  - 認証サーバーから払い出された metadata が入ります
- data_channels- これは DataChannel 経由のシグナリングを有効にしている場合にのみ利用されます
  - 詳細は [DataChannel への切り替え要否の判断](DATA_CHANNEL_SIGNALING.html#1abf7f) をご確認ください
- rpc_methods- これは RPC 機能を有効にしている場合にのみ利用されます
  - 詳細は [RPC 機能を利用する条件](RPC.html#167a95) をご確認ください

### "type": "answer"

クライアントは offer を受け取りしだい、answer 用の SDP を生成します。

```javascript
{
  "type": "answer",
  "sdp": "<Answer 用 SDP>"
}
```

その後、必要があればクライアントは取得した candidate を送ります。

```javascript
{
  "type": "candidate",
  "candidate": "candidate:3179889176 1 tcp 1518214911 192.168.1.10 0 typ host tcptype active generation 0"
}
```


### "type": "disconnect"

クライアントからこのメッセージを送ると、Sora は WebSocket を切断します。また、WebRTC 側も終了します。

クライアントから切断する際には、このメッセージを送るようにしてください。

```javascript
{
  "type": "disconnect"
}
```

オプションとして `reason` を指定することもできます。
この値は [connection.destroyed](EVENT_WEBHOOK.html#6c02d0) の `type_disconnect_reason` として含まれます。

`reason` は最大 128 バイトまで指定することができます。

```javascript
{
  "type": "disconnect",
  "reason": "NO-ERROR"
}
```

### "type": "ping"

サーバーからクライアント側に定期的に送られる通知です。この値をクライアントが受け取った場合は、すぐに以下の JSON を Sora に送信してください。

```javascript
{
    "type": "pong"
}
```

`"type": "ping"` を送ってから指定時間の間に一度も `"type": "pong"` が返ってこない場合、
Sora は正常な通信が行えていないと判断して、Sora からシグナリングの接続を切断します。

指定時間はデフォルトでは 60 秒に設定されており、この値は `sora.conf` の設定 [websocket_signaling_pong_timeout](SORA_CONF.html#140464) で変更できます。

#### stats

> **注意**
>
> この機能は WebSocket 経由でのシグナリングの時のみ有効です

`sora.conf` にて `rtc_stats` を `true` にしている場合は、 `"type": "ping"` 時に `"stats": true` が送られてきます。

```javascript
{
    "type": "ping",
    "stats": true
}
```

この値を受け取った場合は、WebRTC の統計情報を取得して `"type": "pong"` 送信時に `stats` をキーにして値を含んで応答してください。

```javascript
{
    "type": "pong",
    "stats": [{"type": "..."}, {"type": "..."}]
}
```


### "type": "notify"

サーバーからクライアントに対して、参加しているチャネルの情報が通知されるようになります。

詳細は [シグナリング通知機能](SIGNALING_NOTIFY.html) をご確認ください。

### "type": "push"

Sora の [プッシュ API](API_PUSH.html) や [シグナリング通知メタデータ拡張機能](SIGNALING_NOTIFY_METADATA_EXT.html) 、 [音声ストリーミング機能](AUDIO_STREAMING.html) 利用時にクライアントに送信されるプッシュ通知です。

`data` 内に各機能に応じた情報が設定されます。

```javascript
{
    "type": "push",
    "data": {
        <key>: <object>,
        <key>: <object>,
        ...
    }
}
```

## シグナリングエラー

切断時の reason を利用してハンドリングできます。

- Sora のシグナリング失敗時には必ず WebSocket が切断されます。
- どのようなエラーでも、ステータスコードは固定で 4490 が返ってきます。
- reason にはエラーメッセージが入ります

### クライアントに返されるエラーの種類

- `INTERNAL-ERROR`
- `SERVICE-UNAVAILABLE`
- `TIMEOUT`
- `INVALID-MESSAGE`

> **重要**
>
> Sora はライセンスの期限が切れていたとしても、クライアントには **SERVICE-UNAVAILABLE** というエラーを返します。

### `signaling_error.jsonl` に出力される `message` 一覧

- `UNAUTHORIZED`- このエラーはクライアントに通知されることはなく、ログにしか出力されません
- `INTERNAL-ERROR`
- `SERVICE-UNAVAILABLE`
- `TIMEOUT`
- `INVALID-MESSAGE`

### `signaling_error.jsonl` に出力される `details.reason` の一部

* - details.reason
  - 解説
* - connection_created_wait_timeout
  - シグナリングを実行してから Sora と WebRTC の接続が成功するまでの許容時間を超えた場合に出力されるエラー
* - answer_timeout
  - 30 秒以内に "type": "answer" を返さなかった場合のエラー
* - pong_timeout
  - Ping の応答が返ってこなかった場合のエラー
* - duplicated_channel_id
  - 同一の channel_id をすでに使用中の場合のエラー
* - connect_wait_timeout
  - Open したあと一定時間以内に "type": "connect" のメッセージを送信しなかった場合のエラー
* - missing_type
  - type: が JSON に含まれていなかった場合のエラー
* - invalid_json
  - JSON 形式が間違っていた場合のエラー
* - no_media
  - 音声も映像も有効にせずに "type": "connect" を送ってきた場合のエラー
* - unexpected_type
  - シグナリングのフローとして許されない type を受信した場合のエラー
* - unknown_type
  - 未知の type を受信した場合のエラー
* - validate_error
  - シグナリングメッセージのバリデーションに失敗した場合のエラー
* - exceed_max_connections
  - ライセンスの接続数を超えた接続が来た、またはライセンスの期限が切れている場合のエラー
* - bad_fingerprint
  - 証明書検証が失敗した場合のエラー
* - missing_sdp_fingerprint
  - SDP に fingerprint が含まれていない場合のエラー
* - too_many_candidate
  - 多くの "type": "candidate" が送られてきた場合のエラー
* - no_acceptable_node
  - クラスターのどのノードも受け入れられない場合のエラー
* - invalid_signaling_params
  - セッションが残っている状態かつ、接続数が 0 ではない際にシグナリング項目が一致しない接続がきた場合のエラー
* - block_new_connection
  - モードが ``block_new_connection`` のノードに、接続がきた場合のエラー
* - block_new_session
  - ノードのモードが ``block_new_session`` かつ、そのノードが担当していないセッションに対しての接続がきた場合のエラー
* - internal_error
  - 内部エラー

### connection_created_wait_timeout

シグナリングを実行してから Sora と WebRTC の接続が成功するまでの許容時間を超えた場合に出力されるエラーです。

多くの場合はシグナリングの WebSocket は確立したものの、WebRTC の接続が失敗している場合に出力されます。

この許容時間はデフォルトでは 30 秒に設定されており、この値は `sora.conf` の設定 [connection_created_wait_timeout](SORA_CONF.html#0509af) で変更できます。

```ini
// これは 10 秒待っても、シグナリングが成功しない場合は接続を切断する設定です
connection_created_wait_timeout = 10 s
```

> **注釈**
>
> [connection_created_wait_timeout](SORA_CONF.html#0509af) の値を 0 s にすることで、
> 意図的に connection_created_wait_timeout のエラーを発生させることができます。

## シーケンス図


### 認証ウェブフックなし

```mermaid
sequenceDiagram
    autonumber
    participant C as クライアント
    participant S as WebRTC SFU Sora
    participant A as アプリケーションサーバー
    C->>+S: "type": "connect"
    S->>-C: "type": "offer"
    C->>S: "type": "answer"
    C->>S: "type": "candidate"
    note over C,A: WebRTC 確立
    S->>+A: イベントウェブフック<br/>"type": "connection.created"
    A-->-S: 200 OK
    C->>S: "type": "disconnect"
    S->>+A: イベントウェブフック<br/>"type": "connection.destroyed"
    A-->>-S: 200 OK
    S->>C: Websocket Close
```


### 認証ウェブフックあり

```mermaid
sequenceDiagram
    autonumber
    participant C as クライアント
    participant S as WebRTC SFU Sora
    participant A as アプリケーションサーバー
    C->>+S: "type": "connect"
    S->>+A: 認証ウェブフック
    A-->>-S: 200 OK<br/>{"allowed": "true"}
    S->>-C: "type": "offer"
    C->>S: "type": "answer"
    C->>S: "type": "candidate"
    note over C,A: WebRTC 確立
    S->>+A: イベントウェブフック<br/>"type": "connection.created"
    A-->-S: 200 OK
    C->>S: "type": "disconnect"
    S->>+A: イベントウェブフック<br/>"type": "connection.destroyed"
    A-->>-S: 200 OK
    S->>C: Websocket Close
```
