# 本番稼働に向けて

この資料はチュートリアルで Sora をなんとなく体験したあとに、
本番環境に向けてどのような準備が必要なのか、どの機能を使っていけばいいのかをまとめたものです。

不明点などはサポートまでお問い合わせください。

## ログ出力形式の変更

> **重要**
>
> この設定を導入することを強く推奨します

レガシーフォーマットやレガシー拡張を利用せず JSONL 形式や `jsonl` 拡張子での出力を有効にすることを推奨します。

JSONL 形式は `jsonl` 拡張子での出力をする場合は `sora.conf` の [legacy_log_format](SORA_CONF.html#3e05c7) と [legacy_log_extension](SORA_CONF.html#847a26) を `false` にしてください。

## ウェブフックの audio/video のフラット化

> **重要**
>
> この設定を導入することを強く推奨します

レガシーな構成ではなく、フラットな構成を利用することを推奨します。

フラットな構成を利用する場合は `sora.conf` の [legacy_webhook_audio_video_json_structure](SORA_CONF.html#3be597) を `false` にしてください。

## IPv4 アドレスの固定

`sora.conf` の [ipv4_address](SORA_CONF.html#04becc) にサーバーの IP アドレスを指定してください。

```ini
ipv4_address = 192.0.2.10
```

## IPv6 アドレスの利用について

Safari は IPv6 環境での動作が不安定なため、
Safari をターゲットデバイスに含んでいる場合は `sora.conf` の IPv6 設定を無効にする `ipv6 = false` を推奨しています。

ファイアーウォールを利用される場合は IPv6 向け設定もご確認ください。

## sora.conf の turn_fqdn を設定する

iOS の場合は TURN は FQDN を利用しないと接続ができない場合があるため、
TURN-UDP / TURN-TCP で利用するドメインを指定してください。

`sora.conf` の `ipv4_address` に指定した IP アドレスを設定してある FQDN を指定してください。

```ini
turn_fqdn = sora-turn.example.com
```

## HTTP API のループバックアドレスからのみのアクセス

> **重要**
>
> この設定を導入することを強く推奨します

`sora.conf` の [api_loopback_address_only](SORA_CONF.html#9d6140) の値を `true` にしてください。
こうすることでループバックアドレスからのみ HTTP API が叩けるようになります。

## シグナリングのループバックアドレスからのみのアクセス

> **重要**
>
> この設定を導入することを強く推奨します

`sora.conf` の [signaling_loopback_address_only](SORA_CONF.html#e22105) の値を `true` にしてください。
こうすることでループバックアドレスからのみシグナリングが叩けるようになります。

## ファイルディスクリプタ数の設定

Sora は 1 接続で少なくとも 2 つのファイルディスクリプタを利用します。
また、ウェブフックやログの書き込みでも追加でファイルディスクリプタを利用します。
同時接続数が 100 の場合は Linux のデフォルト値である 1024 でも足りますが、
それを超える同時接続がある場合はファイルディスクリプタ数をデフォルトから変更してください。

## systemd の適用

> **重要**
>
> この仕組みを導入することを強く推奨します

Sora の起動/停止に `bin/sora daemon` を利用するのではなく systemd を適用してください。

デーモン化せずに Sora を動かすには `bin/sora foreground` を利用します。

詳細は [systemd](SYSTEMD.html) をご確認ください。


## TURN-TLS、TURN-TCP、シグナリングで 443 番ポートを使用する

> **重要**
>
> この仕組みを導入することを強く推奨します。
> この設定は Sora 2021.1 以降に最適化されています。

> **注意**
>
> nginx および systemd の設定に関する質問については Sora のサポート範囲外となります。

**この設定はある程度の nginx や証明書の知識が必要になります**

nginx のバージョンは 1.11.5 以降が必須です。

TURN-TLS、TURN-TCP、シグナリング（HTTPS）を 443 番ポートのみで受信する場合は次の設定を追加してください。

> **注意**
>
> nginx の停止に QUIT シグナルを使用している場合は、nginx 起動時に作成された UNIX domain socket のソケットファイルは削除されないため、nginx の再起動に失敗します。
> そのため、サービス停止を QUIT シグナルではなく TERM シグナルを使用するように変更するか、または、daemon off で起動することをお勧めします。
> systemd を使用している場合も、ドロップインファイル等を作成して、nginx 停止時のシグナルを QUIT シグナルから TERM シグナルへの変更や、daemon off による管理への変更をお勧めします。

### nginx のストリーム機能と ssl_preread 機能を利用する


nginx の機能を利用して、同一ポートの待受で複数のプロトコルを扱えるようにします。

その機能を利用した nginx の参考設定です。証明書には Let's Encrypt を利用している想定です。

利用する証明書はマルチドメイン (SANs) またはワイルドカード証明書が前提となります。

- sora.example.com- シグナリングの WebSocket over TLS で利用するドメイン
- sora-turn.example.com- TURN-TLS で利用するドメイン

```nginx
stream {
    # SNI のサーバー名が取得できない場合、または、該当するサーバー名が指定されていない場合は TURN-TCP へ
    # 該当するサーバー名が指定されている場合は TURN-TLS または シグナリングへ
    map $ssl_preread_server_name $upstream {
        default sora-turn.example.com;
        "sora-turn.example.com" unix:/tmp/tls.sock;
        "sora.example.com" unix:/tmp/https.sock;
    }

    # Sora の TURN-TCP へ転送
    upstream sora-turn.example.com {
        # Sora の TURN-TCP へ
        # ここの IP アドレスは Sora の ipv4_address に指定した値を指定してください
        # ここを 127.0.0.1 にすると Firefox で繋がらなくなることを確認しています
        server 192.0.2.1:3478;
    }


    # TURN-TCP, TURN-TLS, シグナリングを TCP で待ち受け
    server {
        listen 443;
        # IPv6 を利用している場合は下記を有効にしてください
        # listen [::]:443;

        proxy_pass $upstream;
        proxy_protocol on;

        ssl_preread on;
    }

    # TURN-TLS, シグナリングの TLS 終端し TURN-TCP へ転送
    server {
        listen unix:/tmp/tls.sock ssl proxy_protocol;

        # SNI を見て TURN-TLS の場合は TURN-TCP へ転送
        # シグナリング（HTTPS）の場合は HTTP へ転送
        proxy_pass $ssl_server_name;
        proxy_protocol on;

        ssl_certificate /etc/letsencrypt/live/sora.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/sora.example.com/privkey.pem;

        ssl_protocols TLSv1.2;
        ssl_prefer_server_ciphers on;

        ssl_handshake_timeout 10s;

        ssl_session_cache off;
        ssl_session_tickets off;
    }
}

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    gzip on;

    # $proxy_protocol_addr を利用することでクライアントの IP が保持可能になる
    log_format proxy '$proxy_protocol_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';

    # 定義した proxy を利用する
    access_log /var/log/nginx/access.log proxy;

    server {
        listen unix:/tmp/https.sock ssl proxy_protocol;

        root /var/www/html;

        index index.html index.htm;

        ssl_certificate /etc/letsencrypt/live/sora.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/sora.example.com/privkey.pem;

        ssl_protocols TLSv1.2;

        ssl_prefer_server_ciphers on;

        ssl_session_cache off;
        ssl_session_tickets off;

        real_ip_header proxy_protocol;

        server_name sora.example.com;

        # シグナリングを Sora に Proxy します
        location = /signaling {
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_pass http://127.0.0.1:5000/signaling;

                proxy_set_header X-Real-IP       $proxy_protocol_addr;
                proxy_set_header X-Forwarded-For $proxy_protocol_addr;
        }

        # Sora の HTTP API に Proxy します
        # 本番環境では認証などの機能を利用してください
        location /api {
                proxy_http_version 1.1;
                proxy_pass http://127.0.0.1:3000/;
        }

        # Sora の開発ツールに Proxy します
        # 本番環境では不要です
        location / {
                proxy_http_version 1.1;
                proxy_pass http://127.0.0.1:5000;
        }
    }
}
```

TURN-TCP、 TURN-TLS、シグナリングを 443 番で使用する場合の sora.conf の設定は以下になります。

turn_tcp_port, turn_tls_port を 443 に変更します。

```ini
## TURN 機能を有効にするかどうかを指定してください
turn = true

## TURN 機能で利用するレルムを指定してください
turn_realm = sora-turn.example.com

## TURN 機能で TURN URL 払い出し機能で利用する FQDN (最後の . なし)を指定してください
turn_fqdn = sora-turn.example.com

## TURN 機能で TURN-TCP を有効にするかどうかを指定してください
turn_tcp = true

## TURN 機能で TURN-TCP を有効にした際に利用するポート番号を指定してください
turn_tcp_listen_port = 3478

## TURN 機能で TURN-TCP URL 払い出し時のポート番号を指定してください
turn_tcp_port = 443

## TURN 機能で TURN-TLS URL 払い出し機能を有効にするかどうかを指定してください
## オプションでデフォルトは false です
turn_tls = true

## TURN 機能で TURN-TLS URL 払い出し機能で利用する FQDN (最後の . なし)を指定してください
## turn_tls_fqdn は turn_fqdn の値を上書きします
turn_tls_fqdn = sora-turn.example.com

## TURN 機能で TURN-TLS URL 払い出し機能を有効にした際に利用するポート番号を指定してください
turn_tls_port = 443
```

## カーネルパラメーターの適用

Sora は UDP を利用します。音声や映像の配信では大量の UDP を処理するため Linux のデフォルトの設定だと厳しい場合があります。

そのため、パラメータの変更を推奨しています。

詳細は [Linux カーネルチューニング](LINUX_KERNEL_TUNING.html) をご確認ください。

## SDK の利用

Sora へ接続をする場合は弊社がオープンソースとして公開している SDK を利用してください。


これらのライブラリは弊社によって最新版の Sora で動作するようにメンテナンスされています。

導入もとても簡単になっているので、是非利用してください。

> **重要**
>
> SDK に関する質問・要望・バグなどの報告は Discord の利用をお願いします。
> Sora のライセンス契約の有無に関わらず、
> 応答時間と問題の解決を保証しませんのでご了承ください。
>
> ただし、明らかなバグについては優先的に対応しますので、ご安心ください。



- Sora JS SDK- `#sora-js-sdk` チャンネル
- Sora iOS SDK- `#sora-ios-sdk` チャンネル
- Sora Android SDK- `#sora-android-sdk` チャンネル
- Sora Unity SDK- `#sora-unity-sdk` チャンネル
- Sora C++ SDK- `#sora-cpp-sdk` チャンネル
- Sora Flutter SDK- `#sora-flutter-sdk` チャンネル

## やりたいことが 1:1 の双方向配信の場合

配信が 1:1 の双方向の場合はマルチストリーム機能を利用してください。

詳細は [マルチストリーム機能](MULTISTREAM.html) をご確認ください。

## やりたいことが複数人での双方向配信の場合

複数人で双方向の配信を行いたい場合はスポットライト機能を検討してください。

スポットライト機能を利用することで、クライアントとサーバー側の負荷をかなり抑えられるようになります。

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

## Edge が機能要件に含まれている場合

最新の Edge であれば、ほとんど Chrome と同じ動きをしますので安心してお使いください。

ただし Edge では AV1 は動作しません。

## 認証を外部の指定した HTTP サーバーで判断したい場合

認証ウェブフック機能を利用してください。この機能は外部の指定した HTTP サーバーで認証を判断することが可能になります。

外部の HTTP サーバーの URL 指定は `sora.conf` の [auth_webhook_url](SORA_CONF.html#36a99a) に設定してください。

そうすることで、外部に認証を移譲することができます。

詳細は [認証ウェブフック](AUTH_WEBHOOK.html) をご確認ください。

## 接続、切断の検知を外部の指定した HTTP サーバーで利用したい場合

イベントウェブフック機能を利用してください。この機能は外部の指定した HTTP サーバーでクライアント単位での接続、切断を検知することが可能になります。

外部の HTTP サーバーの URL 指定は `sora.conf` の [event_webhook_url](SORA_CONF.html#e1a4d2) に設定してください。

そうすることで、外部にイベントをリクエスト送信することができます。

詳細は [イベントウェブフック](EVENT_WEBHOOK.html) をご確認ください。

## 配信されている音声や映像を記録したい場合

Sora には録画機能があります。もし利用を検討されている場合はいくつか注意事項があります。

- 録画を終了させる、またはクライアントが切断するまで、録画ファイルは生成されない
- 複数人数が参加する会議の録画ファイルはクライアントごとに生成される- 5 人が会議に参加していれば 5 個ファイルが生成されます

これらを踏まえて録画機能の利用を検討してください。

録画機能の詳細は [録画機能](RECORDING.html) をご確認ください。

## クライアント側で参加してきたユーザーの情報を通知したい場合

Sora では「〜さんが会議に参加しました」や「〜さんが会議から退席しました」というメッセージをクライアント側で流すことが可能です。

これにはシグナリング通知を利用します。

シグナリング通知機能はシグナリングで利用している WebSocket もしくは DataChannel を経由して、参加しているチャネルに新しく参加、または退席した状態を通知する機能です。自分が参加したときも自身に参加通知は飛びます。

ただシグナリング通知に含まれる標準の情報はあくまでコネクション ID のみになるため、そのコネクション ID が誰なのかはどこからか取得する必要があります。

そのコネクション ID が誰なのかを問い合わせる処理が毎回走ってしまうのは無駄なため、認証ウェブフックの戻り値で、 `signaling_notify_metadata` （シグナリング通知メタデータ）にそのコネクション ID の値のユーザー名を含めてください。そうすることで、Sora がその参加者のユーザー名を `signaling_notify_metadata` に含めて返すようになります。

この `signaling_notify_metadata` は新しく参加した人には `data` として、既存の参加している人の `signaling_notify_metadata` が含まれたリストが参加時に通知されるようになっています。

さらに、新しく参加者がいた場合はその参加者の `metadata` が通知されます。もちろん退席者の場合でもその退席者の `metadata` が含まれて通知されます。

`metadata` にユーザー名が含まれるため、サーバーへ問い合わせをしなくても参加者や退席者のユーザー名を取得することができます。

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

シグナリング通知メタデータの詳細は [シグナリング通知メタデータ](SIGNALING_NOTIFY_METADATA.html) をご確認ください。
