Динамическая CDN для WebRTC стриминга с низкой задержкой и контролем доступа к потокам


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


Во второй части мы добавили в CDN выделенные серверы для задач транскодирования, чтобы обеспечить нашим зрителям качество трансляции в зависимости от используемых ими устройств и качества канала. Таким образом, все публикуемые потоки в нашей CDN доступны всем зрителям.


Теперь допустим, что предприятие выходит на этап монетизации и часть потоков должны быть доступны бесплатно, часть — по подписке. Или, например, вебинары для внутреннего обучения сотрудников транслируются одновременно, но для разных филиалов потоки разные, и открывать техники продаж, применяемые в Юго-Восточной Азии, для менеджеров из СНГ нежелательно.


В этих случаях потребуется разграничение доступа подписчиков к публикуемым потокам. Посмотрим, какими способами его можно обеспечить.


Управляем доступом: возможные варианты


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


  1. При установке соединения с клиентом медиасервер передает сообщение на бэкенд-сервер при помощи webhook или REST hook
  2. Бэкенд-сервер возвращает 200 OK, если домен, с которого подключается подписчик, проходит проверку, и 403 Forbidden, если не проходит
  3. Медиасервер устанавливает соединение с подписчиком, если получил от бэкенд-сервера ответ 200 OK, или разрывает его


Если необходимо ограничить доступ к конкретному потоку по его имени, это можно сделать, например, так:


  1. Клиент передает на медиасервер имя потока и ключ доступа
  2. Медиасервер передает эти данные на бэкенд-сервер при помощи webhook или REST hook
  3. Бэкенд-сервер возвращает 200 OK, если доступ к этому потоку по этому ключу разрешен, и 403 Forbidden в противном случае
  4. Медиасервер отдает поток подписчику, если получил от бэкенд-сервера ответ 200 OK, или возвращает клиенту ошибку


Основную часть работы при этом берет на себя бэкенд-сервер. Он должен знать, какие потоки в данный момент доступны в CDN, и какие ключи доступа каким потокам соответствуют. Для бэкенд-сервер должен постоянно опрашивать серверы CDN, чтобы построить для себя список потоков, должен вести некую базу данных с ключами, и должен предоставить определенное API для назначения ключей потокам.


Все это означает большие объемы серверного кода, которые должны быть разработаны заново под каждый проект. Разумеется, использование готовых библиотек упростит разработку, но не интеграцию, даже из деталей от спорткара получится шустрый и красивый, но велосипед.



Можно ли этого избежать? Да, можно, если переложить работу на CDN:


  1. Потокам при публикации назначаются списки ключей доступа, например, при помощи REST API
  2. Клиент при установке соединения передает на медиасервер ключ доступа и имя потока
  3. Медиасервер отдает поток подписчику, если ключ входит в список, назначенный потоку, или возвращает ошибку, если не входит


Посмотрим, как это работает, на примере нашей CDN, развернутой в предыдущих частях.


Переходим на Freemium


Итак, мы вводим подписку на некоторые потоки в нашей CDN. И, поскольку списки контроля доступа для потоков будут передаваться между всем узлами в CDN, первое, что необходимо сделать — переключить CDN на использование шифрованных соединений. Добавляем на всех узлах настройку


wcs_agent_ssl=true

и перезапускаем все серверы в CDN.


Публикуем поток test на сервере o-eu1, играем поток с сервера e-eu1 в примере Player



Отправляем REST API запрос на сервер o-eu1, назначая список контроля доступа потоку test



Поток перестает играть



Поправим исходный код примера Player, чтобы указать ключ доступа к потоку key1


Flashphoner.createSession({urlServer: "wss://e-eu1.flashphoner.com:8443", custom: {aclAuth: "key1"}}).on(SESSION_STATUS.ESTABLISHED, function(session){
    ...
});

Обновим страницу примера и снова проиграем поток



Поток доступен!


Попробуем проиграть этот же поток с ключом key2 из VLC по RTMP с транскодингом




Транскодированный поток также доступен по ключу! Здесь и далее обратите внимание на разницу между WebRTC и RTMP, в первом случае задержка составляет менее секунды, во втором до 2-3 секунд


Предположим, у клиента закончилась подписка. Удалим из списка контроля доступа к потоку test ключ key1



Теперь поток в примере Player недоступен, а в VLC по-прежнему играет!



Проверим, что ключа key1 действительно больше нет в списке



Таким образом, вся работа бэкенда в ограничении доступа к потока в CDN сводится к посылке REST API запросов на Origin серверы, само управление доступом доступно в CDN из коробки.


Заключение


Итак, курс молодого бойца по развертыванию и настройке CDN для стриминга WebRTC потоков с низкой задержкой успешно пройден:


  • сначала мы развернули простую CDN и научились ее масштабировать;
  • затем мы научились транскодировать потоки на выделенных для этого серверах;
  • наконец, мы научились ограничивать доступ к потокам для клиентов.

Конечно, в доставке медиапотоков зрителям есть и множество других нюансов. Например, сейчас в моде виртуальная реальность, а чтобы обеспечить качество трансляции для FullHD и 4K потоков, используемых в этом случае, придется постараться. Но это уже совсем другая история...


Ссылки


CDN для стриминга WebRTC с низкой задержкой — сеть доставки контента на базе Web Call Server.

Источник: habr.ru