Межсерверное WebRTC



    WebRTC умеет работать Peer-to-Peer и Peer-to-Server, где в роли пира, как правило выступает браузер или мобильное приложение. В данной статье мы расскажем о работе WebRTC в режиме Server-to-Server, для чего это нужно и как это работает.

    Масштабирование, Origin-Edge


    Где может понадобиться межсерверное WebRTC? На ум сразу приходит паттерн Origin-Edge, который используется для масштабирования трансляции на большую аудиторию.


    1. Пользователь отправляет WebRTC видеопоток на Origin-WebRTC сервер с браузера или мобильного устройства.
    2. Origin-сервер рассылает поток по нескольким Edge-серверам.
    3. Edge-серверы раздают поток конечным пользователям на их браузеры и мобильные приложения.


    В современных CDN для доставки видео активно используется протокол RTMP при публикации потока на Origin-сервер и при рассылке потока на Edge-сервера, а конечные пользователи получают картинку уже по HTTP.

    Преимуществом WebRTC, по сравнению с данным подходом, может стать гарантированно низкая задержка трансляции, которой нельзя достичь средствами доставки RTMP / HTTP, особенно если ноды разнесены географически.
    Однако для нас межсерверное WebRTC началось не с масштабирования.

    Нагрузочные тесты


    Они были всегда в том или ином виде. Автоматические и полуавтоматические, синтетические и близкие к тому, что делают пользователи. Мы использовали и используем нагрузочное тестирование для отлавливания многопоточных багов, контроля утечек ресурсов, оптимизаций, и многих других вещей, которые нельзя отловить на обычном тестировании.

    На последних тестах мы поднимали Linux-серверы без GUI в облаке и запускали скрипты, стартующие много процессов браузера Google Chrome на виртуальном десктопе X11. Таким образом запускались реальные WebRTC-браузеры, которые тянули и играли WebRTC видеопотоки с Web Call Server, тем самым создавая нагрузку, максимально близкую к настоящей.  Для сервера это выглядело так, словно реальный пользователь открывал браузер и забирал видеопоток, полностью задействуя WebRTC-стек браузера, включая декодинг и рендеринг видео.

    Недостатком этого способа тестирования была производительность тестовой системы. Достаточно тяжело запустить много процессов Chrome на одной Linux-системе, даже при использовании мощного сервера с мегаметрами памяти и CPU. В результате приходилось поднимать много серверов и как-то ими управлять / мониторить.

    Другим ограничением было отсутствие гибкости — мы не могли  управлять процессами хрома. Было только две операции:

    1. Поднять процесс и открыть нужный урл
    2. Убить процесс. При открытии урла подгружалась HTML страница и происходило автоматическое соединение с сервером, уже средствами JavaScript, Websocket + WebRTC. Так моделировалась зрительская нагрузка.

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

    Тестирование WebRTC Server-Server


    Мы пришли к выводу, что ноды нашего сервера сами могут стать генераторами нагрузки, если их правильно подцепить к тестируемым серверам.

    Эта идея получила реализацию в виде WebRTC pulling. Один сервер WCS может вытянуть поток с другого сервера WCS по WebRTC. Для этого мы ввели внутреннюю абстракцию WebRTCAgent — объект, который поднимается на тестирующей ноде и тянет WebRTC-поток с тестируемой ноды, подключаясь к тестируемой ноде по Websocket+WebRTC.

    После этого мы вынесли управление WebRTCAgent-ом на REST. В итоге нагрузочное тестирование свелось к вызову /pull — методов на REST интерфейсе тестирующей ноды.

    При использовании межсерверного WebRTC нам удалось увеличить производительность нагрузочного тестирования примерно в 7 раз и значительно сократить использование ресурсов, по сравнению с той схемой, когда мы запускали процессы Google Chrome. 

    Итак, у нас получилось тянуть WebRTC-потоки с других серверов. Тестирующий сервер подключался к тестируемому по Websocket, и как порядочный браузер, устанавливал ICE-соединение, DTLS и тянул SRTP потоки на себя, — получился true WebRTC pulling.

    Оставалась совсем немного для получения полноценной модели Origin-Edge. Для этого нужно было пробросить такой pulling в движок WCS сервера как публикуемый поток, т.е. сделать его похожим на поток с веб-камеры, а такие потоки WCS уже умеет раздавать по всем доступным протоколам: WebRTC, RTMP, RTMFP, Websocket Canvas, Websocket MSE, RTSP, HLS.

    Origin-Edge на WebRTC


    Получилось, что мы делали межсерверный WebRTC для нагрузочного тестирования, но в результате реализовали Origin-Edge схему для масштабирования WebRTC трансляций, и вот как она работает:

    Зеленой линией показано как проходит видео трафик. 

    1. Пользователь из браузера или мобильного приложения, с помощью вебкамеры, отправляет WebRTC видеопоток с именем stream1 на сервер WCS1 — Origin. Процесс отправки видеопотока с помощью веб примера Two Way Streaming выглядит так:

    А это JavaScript код, который отвечает за публикацию видеопотока через Web API (Web SDK):

    session.createStream({name:'steram1',display:document.getElementById('myVideoDiv')}).publish();

    2.  Далее мы обращаемся к серверу WCS2 — Edge по REST/HTTP API и даем команду забрать видеопоток с Origin-сервера.

    /rest-api/pull/startup
    
    {
    
                    uri: wss://wcs1-origin.com:8443
    
                    remoteStreamName: stream1,
    
                    localStreamName: stream1_edge,
    
    }

    Сервер WCS2 подключается по вебсокетам к серверу WCS1 по адресу wss://wcs1-origin.com:8443 и принимает поток с именем stream1 по WebRTC.

    После этого можно выполнить REST-команду

    /rest-api/pull/find_all

    чтобы вывести все текущие pull-подключения.

    Или команду

    /rest-api/pull/terminate

    чтобы закрыть pull-соединение с Origin WebRTC сервером.

    3. И наконец, забираем поток с Edge-сервера по WebRTC в плеере. Вводим имя потока stream1_edge и начинаем его играть.

    WCS — сервер поддерживает несколько способов воспроизведения. Чтобы поменять технологию, просто тащим вверх MSE или WSPlayer чтобы играть поток не по WebRTC, а по MSE (Media Source Extensions) или в WSPlayer (Websocket — плеер для iOS Safari).

    Таким образом, схема Orign-Edge отработала и мы получили масштабируемость WebRTC-сервера с низкой задержкой.

    Нужно заметить, что масштабируемость работала и раньше по RTMP. WCS сервер умеет делать ре-публикацию входящих WebRTC-потоков на один или несколько серверов по протоколу RTMP. В данном случае, поддержка межсерверного WebRTC стала шагом к снижению общей задержки системы.

    И снова про нагрузочное тестирование


    Для нормального нагрузочного тестирования осталось написать Web-интерфейс в виде REST-клиента, управляющего pull-сессиями. Этот интерфейс был назван Console и принял следующий вид:


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


    Еще предстоит немало сделать и отдебажить. В частности интересно поработать с динамическими битрейтами на межсерверном WebRTC-канале и сравнить межсерверную  проходимость с RTMP. Но уже сейчас у нас есть Orign-Edge на WebRTC и правильные нагрузочные тесты, дающие близкую к реальной нагрузку, что не может не радовать!

    Ссылки


    WCS5 — WebRTC сервер Web Call Server 5
    Two Way Streaming — пример трансляции видеопотока из браузера
    WebRTC Player — пример воспроизведения видеопотока в браузере с возможностью смены технологий WebRTC, MSE, Flash, WSPlayer
    Метки:
    Flashphoner 83,83
    Компания
    Поделиться публикацией
    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое