WebRTC Datachannel для приложений с высокой пропускной способностью

Я хочу отправлять однонаправленные потоковые данные через канал данных WebRTC, и я ищу наилучшие варианты конфигурации (высокая BW, низкая задержка / дрожание) и опыт других с ожидаемыми битрейтами в такого рода приложениях.

Моя тестовая программа отправляет куски по 2 Кб с обратным вызовом события bufferedAmountLowThreshold в 2 КБ и повторяет вызовы до тех пор, пока bufferedAmount не превысит 16 КБ. Используя это в Chrome, я достигаю ~135 Мбит / с в локальной сети и ~20 Мбит / с из / в удаленное соединение, которое имеет 100 Мбит / с WAN-соединение на обоих концах.

Что является ограничивающим фактором здесь?

Как я могу узнать, действительно ли данные будут одноранговыми напрямую или используется сервер TURN?

Мое конечное приложение будет использовать библиотеку google-webrtc на Android - я использую только JS для создания прототипов. Могу ли я установить параметры для ускорения битрейта в библиотеке, чего я не могу сделать в официальных API JS?

1 ответ

Решение

Есть много переменных, которые влияют на пропускную способность, и это также сильно зависит от того, как вы ее измерили. Но я перечислю несколько вещей, которые я настроил для увеличения пропускной способности каналов данных WebRTC.

Отказ от ответственности: я не сделал эти корректировки для libwebrtc, но для моей собственной библиотеки каналов данных WebRTC под названием RAWRTC, которая, кстати, также компилируется для Android. Однако оба используют одну и ту же библиотеку SCTP, оба используют некоторую библиотеку OpenSSL-ish и UDP-сокеты, поэтому все это должно быть применимо к libwebrtc.

Обратите внимание, что реализации канала данных WebRTC, использующие usrsctp, обычно связаны с ЦП при выполнении на той же машине, поэтому имейте это в виду при тестировании. С настройками RAWRTC по умолчанию я могу достичь ~520 Мбит / с на моем i7 5820k. Исходя из моих собственных тестов, и Chrom(e|ium), и Firefox смогли достичь ~350 Мбит / с с настройками по умолчанию.

Хорошо, давайте погрузимся в настройки...

Размер буфера отправки / получения UDP

Стандартный буфер отправки / получения UDP-сокетов в Linux довольно мал по умолчанию. Если вы можете, вы можете настроить его.

DTLS Cipher Suites

Большинство устройств Android имеют процессоры ARM без аппаратной поддержки AES. ChaCha20 обычно лучше работает в программном обеспечении, и поэтому вы можете предпочесть его.

(Это то, что RAWRTC согласовывает по умолчанию, поэтому я не включил его в конечные результаты.)

Размер буфера отправки / получения SCTP

Размер окна отправки / получения по умолчанию для usrsctp, стека SCTP, используемого libwebrtc, составляет 256 КиБ, что слишком мало для достижения высокой пропускной способности при умеренной задержке. Теоретическая максимальная пропускная способность ограничена mbits = (window / (rtt_ms / 1000)) / 131072, Итак, с окном по умолчанию window=262144 и довольно умеренный RTT rtt_ms=20вы получите теоретический максимум 100 Мбит / с.

Практический максимум ниже этого... фактически, намного ниже теоретического максимума (см. Мои результаты теста). Это может быть ошибкой в ​​стеке usrsctp (см. Sctplab / usrsctp # 245).

Размер буфера был увеличен в Firefox (см. Ошибку 1051685), но не в libwebrtc, используемом Chrom(e|ium).

Выпуск сборки

Уровень оптимизации 3 имеет значение (дух!).

Размер сообщения

Вы, вероятно, хотите отправить сообщения размером 256 КБ.

Если вам не нужно поддерживать Chrome выпуск 7774).

Если вам не требуется поддержка Firefox < 56, в этом случае максимальный размер сообщения составляет 16 КиБ (см. Ошибку 979417).

Это также зависит от того, сколько вы отправляете до того, как приостановите отправку (то есть, максимальная отметка буфера), и когда вы продолжите отправку после того, как буфер был опустошен (то есть, нижняя отметка буфера) Мои тесты показали, что при достижении максимальной отметки в 1 МБ и установке минимальной отметки в 256 КиБ достигается достаточная пропускная способность.

Это уменьшает количество вызовов API и может увеличить пропускную способность.

Конечные результаты

Использование уровня оптимизации 3 с настройками по умолчанию в RAWRTC позволило мне достичь ~600 Мбит / с.

Исходя из этого, увеличение размеров буфера SCTP и UDP до 4 МБ позволило мне подняться до ~700 Мбит / с с одним ядром ЦП при 100% нагрузке.

Тем не менее, я считаю, что еще есть возможности для улучшений, но вряд ли это будет зависать.


Как я могу узнать, действительно ли данные будут одноранговыми напрямую или используется сервер TURN?

открыто about:webrtc в Firefox или chrome://webrtc-internals в Chrom(e|ium) и ищите выбранную пару кандидатов ICE. Или используйте Wireshark.

Другие вопросы по тегам