Twilioとネットワーク(QoS)と通話品質

# Twilioとネットワークと私

こんばんは、冬ですね。
気がつけば二年ぶりの投稿でした。

この半年ほど、Twilioでコールセンター的なシステムを作っている人のお手伝いをしています。

その方から「Twilioアドベントカレンダー書かないんスか？」と言われたとき、
正直、こんなTwilioハッカーズが集まる場所で書けることねぇよ、と思ってたんですが、
ちょうど音質周りのことでネットワーク周りの調査や調整をしていたので、
せっかくなのでまとめておこうと思います。

Twilioの使った範囲はWebRTCでの通話周りだけなので、
iOSアプリとか、ビデオ、SMS周りなんかはまた違うことがあるかもしれませんのでご了承ください。

# ネットワーク周りを調整したきっかけ

既にリリース済みのプロダクトだったので、最初は機能改修などを担当していたのですが、
そのうち、現場から以下のような声が届いていることを知りました。

* 音がぷつぷつして相手に聞き返されることがある
* こっちの声が全く相手に聞こえてないことがある

通話録音にも残っていたので、現場から報告された内容をきっちりと確認できました（便利）

そして調べているうちに、下記の記事にたどり着き、もしかしてネットワーク関連の問題なのではと思いQoSを設定する方向に進むことになりました。

[Twilio Client 環境構築におけるベストプラクティス – Twilio for KDDI Web Communications](https://twilioforkwc.zendesk.com/hc/ja/articles/360000036881-Twilio-Client-%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9)


# QoS（優先制御）の設定

## 設定したルーター

YAMAHA RTX-3500, RTX-1210, RTX-1200。

## Twilioが通信するポート

以下のページに記載されています。

[What are Twilio Client's Network Connectivity Requirements? – Twilio Support](https://support.twilio.com/hc/en-us/articles/223180888-What-are-Twilio-Client-s-Network-Connectivity-Requirements-)

シグナリングには`443`のTCPポート、RTPには`10000-20000`のUDPポートが使用されています。
今回は、通話の品質改善が目的ですので、RTPで使っているUDPのパケットを優先的に流すようにQoSの設定を行います。

また、RTPの接続先は`Static IP range`とのことで、上記のページにリンクから辿ると、静的に決まっていることがわかります。

[Twilio Client Regions - Twilio # Region information for twilio.js](https://www.twilio.com/docs/voice/client/regions#twilio-js-regions)

jp1サーバーを使用する場合は `54.65.63.192 - 54.65.63.255` が接続先のIPとなります[^2]

## コマンド

WANがLAN2に設定されている場合は以下のようになります。

```
speed lan2 40m
queue lan2 type priority
queue lan2 class filter list 1 2
queue class filter 1 4 ip * 54.65.63.192-54.65.63.255 udp * 10000-20000
queue class filter 2 2 ip * *
```

PPPoEの場合はこんな感じ。

```
speed lan2 40m
queue lan2 type priority
queue class filter 1 4 ip * 54.65.63.192-54.65.63.255 udp * 10000-20000
queue class filter 2 2 ip * *
pp select 1
# pppoe use lan2
queue pp class filter list 1 2
no pp select
```

* 上り帯域は40Mbpsに制限されます
    * speedを設定しないと、NICの最大速度でqueueを処理しようとするので効果がでません
* TwlilioのRTPのみclass4に割り振られ優先的に処理されます
* それ以外は通常の優先度（class2）になります 
* PPPoEの場合は、pp側でclass filterを設定し、LAN側で優先制御させる感じになります

### 参考公式ドキュメント

* [優先制御/帯域制御とVoIP](http://www.rtpro.yamaha.co.jp/RT/FAQ/Queue/queue-and-voip.html)
* [優先制御のふるまい](http://www.rtpro.yamaha.co.jp/RT/FAQ/Queue/queue-type-priority.html)
* [28.2 クラス分けのためのフィルタ設定](http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/queue/queue_class_filter.html)
* [28.3 キューイングアルゴリズムタイプの選択](http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/queue/queue_interface_type.html)
* [28.5 クラス分けフィルタの適用](http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/queue/queue_interface_class_filter_list.html)

## 設定の確認

設定後、実際にTwilioで発信を行ったあとに、`show status qos all`で以下のように表示されるとQoSが設定されています。

```
> show status qos all
LAN2
Queueing Type:                  priority
Interface Speed:                40m
[Bandwidth]
Class   Set Bandwidth          Used Band (%)  Peak    Record Date
------- ---------------------- ------------   ------  -------------------
  1     -                         0  (  0%)      0    ----/--/-- --:--:--
  2     -                       311k (< 1%)    425k   2018/12/05 16:02:54
  3     -                         0  (  0%)      0    ----/--/-- --:--:--
  4     -                         0  (  0%)   95.7k   2018/12/05 16:01:04
------- ---------------------- ------------   ------  -------------------
Total of Class:                 4
Total of Guaranteed Bandwidth:  -
[Queue Length]
Class  Limit    Enqueued Times       Dequeued   Now  Peak  Record Date
               success / failure        Times
------ ----- --------------------- ---------- ----- -----  -------------------
  1      200          0/         0          0     0     0  ----/--/-- --:--:--
  2      200       7817/         0       7817     0    23  2018/12/05 15:58:50
  3      200          0/         0          0     0     0  ----/--/-- --:--:--
  4      200       3993/         0       3993     0     3  2018/12/05 15:59:55
------ ----- --------------------- ---------- ----- -----  -------------------
```

## 通話品質が改善したか

ネットワークに負荷をかけた状態で通話を試しても、通話品質に問題が出ることはなかったので、QoS自体は正常に動作していることが確認できました。

が、これだけで通話品質が全て改善したかというと…そうでもありません。
未だに通話品質が良くない事例もあるので、VoIPって難しいなぁという感じる日々です。

ですが、Twilioは本当にいろんな可能性を秘めた素晴らしいプロダクトですので、いろいろ今後も使い倒していきたいと思います。

# おまけ

## 他に通話品質に関連してたこと

* PCのメモリが少なくて使い切ってた
* ネットワークハブが不調だった
* プロバイダ側の輻輳でパケットロスが止まらない
* 特定のWindows10のPCで、NICのドライバの省電力設定がONになっていると、通話開始時の20秒ほど相手に届く声が途切れる
    * しかもInsightsにものらない

などなど。
いやー、大変ですね。

## ベストプラクティスの中でQoS以外で既に対応済みだったこと

### WiFiではなく有線LANで接続する

こちらは当初より徹底して現場に周知していただきました。
基本中の基本ですので、Twilioの通話で**音質を重視する場合は**必ず有線LANで接続しましょう。

音質を特に気にしないのであれば、WiFiの環境が悪くない限り[^1]そこそこ普通に会話できる感じです。

### USBヘッドセットを使う

> ロースペックのPCやハードウェアを使う場合は、USBヘッドセットのほうが良い結果を生むことが多いです。3.5mmジャックのタイプと違い、オーディオカードへネイティブな音声をバイパスできるためです。

とのことです。
担当した環境では、全員JabraのUSBヘッドセットを使っていたので対応済みでした。

## api.twilio.comは遠い

これ音質とは関係ないですが `api.twilio.com` はUSのEC2にあるので、受電の応答など時間にシビアなタイミングで何度も呼び出すような設計にしてしまうと結構時間がかかるので、サーバーサイドでいろいろやりたい場合は呼び出し回数を減らすなど工夫したほうがよいです。




[^1]: むかーしむかし、[WLX302](https://network.yamaha.com/products/wireless_lan/wlx302/index)の「見える化機能」使ったけど、本業のインフラ屋じゃない私ぐらいの知識でもそこそこ環境を良くすることができたことを思い出した。WiFiの状態をいい感じに保つのって難しいですよね。
[^2]: ちなみに、RTPの接続先のIPはAWSのap-northeast-1です。なので、北海道とか九州とかでTwilioを使うと、どうやってもレイテンシーが20msほどプラスになります。まぁ、通話してても気付きませんが。