WebRTC — не самая простая штука. Только недавно API стали поддерживать все основные браузеры, но с оговорками и «нюансами». Добавим к этому темное наследие VoIP телефонии в виде торчащего наружу SIP, борьбу между Ёжиком и SIP с применением oRTC, падающие при неудачном сочетании звезд браузеры — и получаем штуку, которую не в любом коворкинге за вечер запилишь. Цахи, бессменный автор bloggeek.me и старый телеком-разработчик, продолжает писать как все это правильно готовить. А мы в Voximplant адаптируем перевод для Хабра, основываясь на собственном многолетнем опыте голосовых и видеозвонков с участием браузеров.
Почему у нас не получается с WebRTC?
Как разработчик и консультант я слишком много раз видел талантливых программистов, у которых не получалось с WebRTC. Они делали типичные для новичков ошибки, а это не тот тип ошибок, которые я хочу совершать во время затопления моей квартиры. Я вижу фейлы талантливых разработчиков с WebRTC намного чаще, чем с другими технологиями. Известная цитата Марка Твена:
Нет такой вещи, как новая идея. Это невозможно. Мы просто берем кучу старых идей и помещаем их в мысленный калейдоскоп. Вращаем его, и идеи создают новые занимательные комбинации. Продолжаем вращает и создавать новые комбинации бесконечно; но это все те же кусочки цветного стекла, которые мы использовали веками.Это высказывание о корне многих детских ошибок с WebRTC. Технология такая же «новая», как узоры в калейдоскопе Марка Твена. Просто набор старых идей, замешанных в свежую, интересную комбинацию. Мы знаем это, и полагаем, что умеем работать с такими штуками.
Бизнесмены? Скайпу 14 лет. Это не должно быть очень сложно создать что-то наподобие скайпа в наши дни.
Разработчики VoIP? Мы знаем SIP. WebRTC похож на SIP без сигнализации. Так что мы прикрутим туда SIP и все готово.
Web разработчики? WebRTC является частью HTML5. Несколько строк JavaScript кода и почти готово для релиза.
Разработчики видеосервисов? Мы же можем просто взять WebRTC видеопоток и положить на CDN?
Результат?
- Хорошие разработчики полагают, что они знают достаточно, чтобы сделать все без посторонней помощи. Все заканчивается очень интересными ошибками.
- Мы верим специалисты в одной из перечисленных областей. Все заканчивается провалом.
Недавно я офигел с команды, которая в 2018 году решила использовать библиотеку PeerJS для своего WebRTC приложения. PeerJS, на секундочку, это 402 строки JavaScript кода, которые последний раз обновлялись в 2015 (!) году. Такой старый код просто нельзя использовать для работы с WebRTC! Код старше года уже мертв или засахарился. WebRTC все еще слишком новый и слишком быстро меняется.
Выбора у нас, кстати, особо не осталось. Flash умирает, и другой серьезной альтернативы WebRTC нет. Если вы хотите использовать WebRTC в своих проектах, то вот пять типовых ошибок, которые лучше не совершать.
Ошибка №1: Неправильно настроенный STUN/TURN
Вы не поверите, насколько часто разработчикам не удается настроить сервера для обхода NAT. Вчера кто-то спросил через чат-виджет моего сайта как они могут развернуть свое приложение и сигнализацию с помощью HostGator без использования STUN/TURN серверов.
Простой ответ: никак. За исключением нескольких эзотерических случаев вам понадобятся STUN сервера. А для большинства практических применений еще и TURN сервера, если вы хотите, чтобы ваши сессии соединялись друг с другом. Только за предыдущий месяц я рассказывал о NAT traversal следующее:
- Нужно использовать и STUN, и TURN сервера.
- Не надейтесь на бесплатные STUN сервера (например, широко известные «stun.l.google.com:19302») и тем более на «бесплатные» TURN сервера.
- Не отправляйте все сессии через TURN, если вы совершенно точно не знаете зачем это вам.
- Использование TURN не дает никакой дополнительной защиты для соединений.
- Вам не нужно передавать WebRTC больше одного STUN и трех TURN серверов (UDP, TCP и TLS).
- Для настройки TURN используйте временные или ephemeral пароли в настройках TURN.
- STUN сервер никак не влияет на качество звука и видео.
- cotun или restund — хороший выбор STUN/TURN сервера.
Это не все, но достаточно для начала.
Ошибка №2: Выбор неправильного фреймворка для сигнализации
PeerJS? Выглядит как типичная «ловушка для туриста»:
У проекта 1'693 звезды и 499 форков, это один из самых популярных репозиториев на github, относящихся к WebRTC. Что может пойти не так?
Возможно, то, что проект чуть менее старый, чем интернет?
Проект, относящийся к WebRTC, последний коммит в который сделан более трех лет назад, просто не может быть использован в 2018 году. То же относится к примерам кода от Muaz Khan — не стоит рассчитывать, что они коммерческого уровня, стабильны и масштабируемые. Нет. Просто полезные примеры кода.
Планируете использовать какой-нибудь другой open source проект? Убедитесь, что:
- У проекта были обновления в последние несколько месяцев.
- Он достаточно популярен.
- Вы можете понять код проекта и, в случае необходимости, что-то в нем поменять.
- Вы можете связаться с кем-нибудь из майнтейнеров, если вам понадобится (платная) помощь.
Отнеситесь серьезно к выбору серверов для сигнализации и передачи данных.
Ошибка №3: Не использовать медиа сервер когда это нужно
Я знаю, о чем думают разработчики, использующие WebRTC. Технология умеет peer-to-peer, поэтому сервера не нужны. Некоторые даже считают, что можно обойтись без сигнализации и веб серверов. Надеюсь, они могут при этом объяснить, как браузеры участников в таком случае найдут друг друга, чтобы совершить peer-to-peer звонок.
Для многих концепция peer-to-peer также означает, что можно создавать сессии с большим количеством участников без серверов для передачи медиаданных. У меня даже есть два примера такой «архитектуры»:
Сферический меш в вакууме. Круто. Но не думайте, что получится заставить такую штуку работать как надо в этом или следующем году. Двигаемся дальше:
Броадкаст в реальном времени с помощью форвардинга. Такое можно сделать, но результат будет далек от ожидаемой масштабируемости на миллионы участников с нулевой задержкой.
На практике нам нужны медиа сервера для передачи медиа данных: голоса и видео. Теперь, когда вы об этом знаете, можно поискать open source или коммерческое решение.
Ошибка №4: Тактика без стратегии
Вы нашли хорошего аутсорсера, скормили ему требования к продукту, заплатили и получили на выходе работающее решение. Все проблемы позади?
Нет.
Сама технология WebRTC еще очень молода. Официальная спецификация меняется. Ее имплементация в браузерах меняется. Все это находится в постоянном движении. Если вы хотите использовать WebRTC, то я рекомендую вам остановиться на одном из двух вариантов:
- Использовать готовую платформу (вот несколько, Voximplant там есть) и обменять часть стоимости разработки и поддержки на ежемесячные платежи.
- Разработать собственное решение (или отдать разработку на аутсорс). В этом случае вам нужно будет инвестировать в поддержку проекта года на 3, если не больше.
Код WebRTC гниет быстрее, чем любой другой HTML5 код. Когда-нибудь перестанет, но явно не сейчас. По этой причине я вместе с несколькими коллегами несколько лет назад создал testRTC: чтобы помочь в разработке решений с использованием WebRTC, особенно в части тестирования и мониторинга.
Ошибка №5: Непонимание как работает WebRTC
Они говорят, что допущение — это причина всех ошибок. Гугл с этим вроде бы согласен. Вроде бы.
WebRTC не самая тривиальная технология, расположенная где-то на пересечении VoIP и веба. Она новая, и по ней не так много информации. А та, что есть, меняется очень часто (вывод: большая часть этой информации уже успела устареть).
Если вы собираетесь использовать WebRTC, то убедитесь, что понимаете технологию и область ее применения. Какие требуется развернуть сервера. Как WebRTC взаимодействует с сигнализацией (signaling — обмен данными между браузерами или другими WebRTC устройствами чтобы понять кто где в сети находится и какие медиа данные куда надо передавать). Как обрабатываются и передаются по сети медиа данные: голос, видео и «пользовательские». Какие есть готовые решения для работы с WebRTC.
Много разных штук для изучения. Не полагайтесь на свои знания Web, VoIP или видео-технологий. WebRTC сможет вас удивить.
Комментарии (15)
Ovoshlook
15.03.2018 13:43+1Самые главные ошибки построения сервисов на базе webRTC в том, что:
1 Каждый второй строит свой велосипед на уровне сигнализации, в итоге получая проприетарщину, котороая к тому же не работает.
2 Каждый второй не понимает как работает медиа и что вообще написано в SDP и не пытается понять.
Ну это — если не считать публичных STUN/TURN/ICE Серверов в продакшнах.
inoyakaigor
16.03.2018 14:35+1Меня вот интересует вопрос почему нельзя обойтись без медиасервера?
eyeofhell Автор
16.03.2018 15:06Можно. Для peer-to-peer звонков. У нас в Voximplant до 1000 пользователей в месяц peer-to-peer вообще бесплатно.
Проблемы начинаются, когда в 20% случаев Peer-to-peer не получается и нужно или идти через TURN, или через медиа сервер. Или когда нужно писать голос/видео на стороне сервера. Или когда нужно делать голосовую/видеоконференцию на много человек. Вообщем для большинства практических задачь понадобится медиа сервер. А в простых случаях и для разработки можно без него, да. Я как-то демку показывал, где два MS Edge делали видеозвонок даже без сигналинга — я копипастил между ними офферы и ансверы :)
akadex
17.03.2018 12:46+1Я вот все прицеливаюсь в своих продуктах на конференции для корпоративной связи. Понимаю, что достаточно сервисов, но так сложилось, что почти всегда идёт интеграция с локальной софтварной АТС. То бишь с аудиочастью проблем нет, но вот видео иногда требуется. Так вот из того что понравилось больше всего для этой цели — это FreeSwitch Verto. Можно долго рассказывать, но рекомендую всем. Очень не дурно реализовано.
eyeofhell Автор
17.03.2018 12:46FreeSwitch и Asterisk — классические решения для сборки самому. Именно с них к нам в Voximplant переходит больше всего клиентов :)
akadex
17.03.2018 12:53+1А у Вас ПО — это полностью самостоятельная разработка в части медиа-сервера?
eyeofhell Автор
17.03.2018 13:06Увы, да. Когда миллионы звонков — нужен полный контроль над происходящим. Чтобы не текло, не падало и без сюрпризов. Несколько сильных VoIP плюсовиков-затейников, несколько лет разработки, никакой магии.
HexArt
После прочтения статьи возникло несколько вопросов. Можете ответить?
1. Чем плохи публичные STUN сервера? Например тот же stun.l.google.com:19302
2. На сколько я понимаю использовать STUN или TURN решает WebRTC. Если нет, то как это происходит?
3. Чем плохо указывать 2-3 STUN сервера?
4. Я не совсем понял проблему использования PeerJS. Сигнализация же ни как не связана с WebRTC и может быть любой. Что конкретно может пойти не так?
Softer
1. ИМХО — полагаю что это просто неразумно:
eyeofhell Автор
1. Он тестовый. То есть в любой момент может сделать ой, или затупить на несколько минут, или вернуть странное.
2. При инициализации WebRTC мы передаем ей список серверов. Далее предлагаем сделать offer и движок начинает с ними общаеться. Делает offer, мы через сигнализацию передаем его второму браузеру и предлагаем ему сделать answer. Тот тоже начинает с серверами общаться. Затем передаем answer обратно и по паре offer-answer первый браузер решает, как коннектиться. В процесс можно вмешиваться руками, меняя offer/answer перед тем, как передать его движку (это просто строка текста или объект для oRTC).
3. Вот тут я не знаю, к сожалению. irbisadm?
4. PeerJS вызывает API WebRTC и рассчитывает на определенное поведение. Которое уже успело сильно поменяться.
HexArt
Про PeerJS понял, спасибо. Мы используем WebSocket и таких проблем нет.
А вот зачем менять offer/answer руками не понял. Какая в этом может быть выгода?
eyeofhell Автор
Если, к примеру, SDP роняет браузер на той стороне :) Или в оффере слишком маленький битрейт по умолчанию предлагается. Множество причин может быть.
Ogra
STUN используется только при установке соединения и нужен практически всегда, если вы сидите за любым NAT (вроде роутера).
TURN же используется только если не удается установить соединение напрямую, нужен для p2p соединений, когда a) оба собеседника за NAT, b) NAT определенным образом сконфигурирован и соединение по определенным через STUN адресам невозможно. При использовании публичного медиа-сервера не нужен.
WebRTC будет использовать STUN, если его указать. Сходит к серверу, получит внешний ip:port, но если оба клиента в локалке, то использоваться будут локальные адреса, а не внешние. В принципе, возможна ситуация, что коннект по локалке произойдет до того, как браузер попробует получить внешний адрес. Но это тестировать надо ;)
WebRTC будет использовать TURN, только если прямые, более приоритетные способы невозможны.
HexArt
В статье написано:
В вашем комментарии все верно. Я просто не понял, зачем надо руками вмешиваться в эту работу.
Ogra
По идее, если не указать STUN сервера, а указать тольк TURN, то куча соединений пойдет через TURN. Но я не пробовал и никому не советую ;)