# Sora クライアント要求仕様

## 概要

Sora SDK や Sora クライアントの開発者に向けた資料です。

## クライアント側の終了処理条件

### RTCPeerConnectionState が failed になる

すべての接続において [RTCPeerConnectionState](https://www.w3.org/TR/webrtc/#dom-rtcpeerconnectionstate) が [failed](https://www.w3.org/TR/webrtc/#dom-rtcpeerconnectionstate-failed) になったタイミングで `"type": "disconnect"` は送らず、
クライアント側で終了処理をしてください。

### WebSocket のみ

- RTCPeerConnectionState が failed になった- 終了処理に入る
- WebSocket onclose が上がった- 終了処理に入る
- WebSocket onerror が上がった- 終了処理に入る

### WebSocket と DataChannel

- RTCPeerConnectionState が failed になった- 終了処理に入る
- WebSocket onclose が上がった- `"type": "switched"` が送られてきていない- 終了処理に入る
  - `"type": "switched", "ignore_disconnect_websocket": true` が送られてきていた- 何もしない
  - `"type": "switched", "ignore_disconnect_websocket": false` が送られてきていて、 RTCPeerConnectionState が failed になっている- 終了処理に入る
  - `"type": "switched", "ignore_disconnect_websocket": false` が送られてきていて、 RTCPeerConnectionState が failed になっていない- DataChanel で `"type": "disconnect", reason: "WEBSOCKET-ONCLOSE"` を送ることを試みる
    - 終了処理に入る
- WebSocket onerror が上がった- `"type": "switched"` が送られてきていない- 終了処理に入る
  - `"type": "switched", "ignore_disconnect_websocket": true` が送られてきていた- 何もしない
  - `"type": "switched", "ignore_disconnect_websocket": false` が送られてきていて、 RTCPeerConnectionState が failed になっている- 終了処理に入る
  - `"type": "switched", "ignore_disconnect_websocket": false` が送られてきていて、 RTCPeerConnectionState が failed になっていない- DataChanel で `"type": "disconnect", reason: "WEBSOCKET-ONERROR"` を送ることを試みる
    - 終了処理に入る

### DataChannel のみ

- RTCPeerConnectionState が failed になった- 終了処理に入る

### DataChannel の終了

Sora SDK の切断タイムアウトのデフォルト値は 3000 ミリ秒です。

- RTCDataChannel [onclose](https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onclose) が上がった- RTCDataChannel [onerror](https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onerror) にコールバックをセットしている場合- 終了処理に入る、または切断タイマーを開始し、すべての RTCDataChannel の [readyState](https://www.w3.org/TR/webrtc/#dom-datachannel-readystate) がすべて [closed](https://www.w3.org/TR/webrtc/#dom-rtcdatachannelstate-closed) にならずタイムアウトした場合は終了処理にはいる
  - RTCDataChannel onerror にコールバックをセットしていない場合- 終了処理に入る
- RTCDataChannel onerror が上がった- 終了処理に入る

## アプリケーション経由の "type": "disconnect" 送信後の終了処理

Sora SDK の切断タイムアウトのデフォルト値は 3000 ミリ秒です。

### WebSocket のみ

`data_channel_signaling: false` の場合。

- WebSocket 経由で `"type": "disconnect", reason: "NO-ERROR"` を送る- 終了処理に入る、または切断タイマーを開始し、WebSocket onclose が上がらずタイムアウトした場合は終了処理に入る

### WebSocket と DataChannel

`data_channel_signaling: true` で `ignore_disconnect_websocket: false` の場合。

- `"type": "switched"` が送られて来ていない- WebSocket 経由で `"type": "disconnect", reason: "NO-ERROR"` を送る
  - 終了処理にはいる、または切断タイマーを開始し、WebSocket onclose が上がらずタイムアウトした場合は終了処理にはいる
- `"type": "switched", "ignore_disconnect_websocket": false` が送られてきていて、 WebSocket は切断していない- DataChannel 経由で `"type": "disconnect", reason: "NO-ERROR"` を送る
  - [RTCDataChannel](https://www.w3.org/TR/webrtc/#dom-rtcdatachannel) [onerror](https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onerror) にコールバックをセットしている場合- 終了処理に入る、または切断タイマーを開始し、WebSocket の onclose かつ、すべての RTCDataChannel の [readyState](https://www.w3.org/TR/webrtc/#dom-datachannel-readystate) がすべて [closed](https://www.w3.org/TR/webrtc/#dom-rtcdatachannelstate-closed) にならずタイムアウトした場合は終了処理にはいる
  - [RTCDataChannel](https://www.w3.org/TR/webrtc/#dom-rtcdatachannel) [onerror](https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onerror) にコールバックをセットしていない場合- 終了処理に入る

### DataChannel のみ

`data_channel_signaling: true` で `ignore_disconnect_websocket: true` の場合。

- `"type": "switched"` が送られて来ていない- WebSocket 経由で `"type": "disconnect", reason: "NO-ERROR"` を送る
  - 切断タイマーを開始する
  - WebSocket onclose が上がらずタイムアウトした場合は終了処理に入る
- `"type": "switched", "ignore_disconnect_websocket": true` が送られてきていて、 WebSocket も切断している- DataChannel 経由で `"type": "disconnect", reason: "NO-ERROR"` を送る
  - RTCDataChannel [onerror](https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onerror) にコールバックをセットしている場合- 終了処理に入る、または切断タイマーを開始し、すべての RTCDataChannel の [readyState](https://www.w3.org/TR/webrtc/#dom-datachannel-readystate) がすべて [closed](https://www.w3.org/TR/webrtc/#dom-rtcdatachannelstate-closed) にならずタイムアウトした場合は終了処理にはいる
  - RTCDataChannel onerror にコールバックをセットしていない場合- 終了処理に入る

## 異常発生による終了

### シグナリングの異常

終了処理に入ってください。

### シグナリング以外の異常

`"type": "disconnect", reason: "INTERNAL-ERROR"` を送り、終了処理に入って下さい。

## ライセンスエラーによる終了

`"type": "connect"` を送った際、ライセンスの期限が過ぎていたり、最大同時接続数を超えた場合、
Sora はエラーメッセージ `SERVICE-UNAVAILABLE` を送信し、 WebSocket を切断し終了します。

## RTCPeerConnectionState が定義されていない場合

> **注釈**
>
> ブラウザでは Firefox が RTCPeerConnectionState が定義されていません

[RTCDtlsTransport](https://www.w3.org/TR/webrtc/#dom-rtcdtlstransport) が実装されていない場合 RTCPeerConnectionState が正常に動作しないため、
[RTCIceConnectionState](https://www.w3.org/TR/webrtc/#dom-rtciceconnectionstate) を利用してください。

RTCIceConnectionState が [disconnect](https://www.w3.org/TR/webrtc/#dom-rtciceconnectionstate-disconnected) になった場合、切断タイマーを開始し、
タイムアウトした場合 disconnect から変化がなければ切断してください。

Sora SDK の RTCIceConnectionState 用の切断タイマーはデフォルトで 10 秒です。

## クライアントの状態

### 認証失敗

接続を試みて、認証ウェブフックが接続を許可しなかった状態です。

Sora は認証失敗理由を WebSocket で送信後に、WebSocket を切断します。

### 認証成功

接続を試みて、認証ウェブフックが接続を許可した状態です。

この時点ではまだ WebRTC での接続に成功していません。そのため、同時接続数としてもカウントされません
認証は成功しているが、WebRTC での接続に失敗するということがありえるためです。

### セッション参加

認証が許可されると、そのチャネル ID のセッションが存在していれば **セッションへの参加** が行われます。
もしセッションが存在していなければ **セッションの生成** が行われます。

この時点ではまだ WebRTC での接続に成功していません。そのため、同時接続数としてもカウントされません
認証は成功しているが、WebRTC での接続に失敗するということがありえるためです。

認証が成功したタイミングで、 Sora はクライアントをセッションに参加させます。
この後、クライアントは Sora からの `"type": "offer"` を受け取り、WebRTC の確立を試みます。

### セッション離脱

セッションからの離脱は、コネクションが破棄された後に発生します。

セッションが API で破棄されたり、セッションのライフタイムが終了した場合、
そのセッションに参加しているクライアントのコネクションを破棄し、セッションから離脱します。

### コネクション生成

認証が成功し、セッションへ参加後、WebRTC のコネクションが確立された状態です。

つまり [connection.created](EVENT_WEBHOOK.html#eef06c) ウェブフックが送信されたタイミングになります。

このタイミングで Sora は初めて同時接続数に +1 をします。

### コネクション破棄

何かしらの理由で、WebRTC のコネクションが破棄された状態です。

このタイミングで Sora は同時接続数から -1 をします。

## クライアントからの "type": "disconnect" による切断

WebSocket シグナリングを利用している場合は、 WebSocket の Close フレームの Reason に `"TYPE-DISCONNECT"` が入るようになりました。

DataChannel シグナリングのみを利用している場合は、 DataChannel を閉じて終了します。

## WebSocket シグナリング利用時に Sora から正常切断

切断系 API やライフタイム期限などの Sora からの正常切断時に、
WebSocket シグナリングを利用している場合、
WebSocket Close フレームの Code に 1000 、 Reason に切断理由が入ります。

正常な場合の切断理由は以下の 3 つです。

- `LIFETIME-EXPIRED`- ライフタイムによるコネクションの破棄
- `SESSION-DESTROYED`- API やライフタイムなどによるセッションの破棄
- `DISCONNECTED-API`- API によるコネクションの破棄

## DataChannel シグナリングのみ利用時に Sora から切断が発生した際の `"type": "close"` メッセージの送信

DataChannel シグナリングのみ利用時に Sora から切断が発生した際、
DataChannel を閉じる前に `"type": "close"` メッセージを送信します。

`sora.conf` の [data_channel_signaling_close_message](SORA_CONF.html#058a1e) を `true` に設定することで有効になります。
デフォルトは `false` です。

DataChannel が閉じられたのが正常な処理なのか、それとも何か問題が発生したのかを明確にするための仕組みです。

正常な場合の切断理由は以下の 3 つです。

- `LIFETIME-EXPIRED`- ライフタイムによるコネクションの破棄
- `SESSION-DESTROYED`- API やライフタイムなどによるセッションの破棄
- `DISCONNECTED-API`- API によるコネクションの破棄
