Всем привет. Меня зовут Дмитрий, и я типичный представитель касты гребцов на галере X. Основной ЯП, который я использую - PHP, но иногда приходится писать на других.

Предыстория

Как-то пришел очередной, немного не доделанный, проект "убийца" продукта Y. Все бы ничего, если бы его не делали изначально индусы. Первоначальный анализ кода и все оценкой фич занимался другой разработчик. В итоге было решено взять наследие индусов, немного подправить и в прод.

Немного подправить и в продакшн, растянулось где-то на пол года. Все уже к этому времени поняли что лучше бы выбрали вариант - переписать заново, но было уже поздно, а отступать назад не хотелось. В итоге проект выехал live, но был чертовски страшный и неудобный со стороны UI/UX. Поэтому начался плавный редизайн всего и вся. Все что описано выше, было до меня, я пришел на проект только через пол года.

Постановка задачи и начальные условия

Новый спринт, новые тикеты. Одна из задач звучит как: "Редизайн текущего механизма видео/аудио звонков". Для данного функционала мы использовали Agora Web SDK 3.4.0v. Почему именно Agora - потому что ее выбрали индусы (скорее всего из-за 10000 бесплатных минут). Возможно еще подкупило то что есть SDK под различные платформы:

Поехали

Первый делом я глянул последнюю версию Web SDK. Как оказалось - уже вышла абсолютно новая мажорная версия Agora Web SDK 4.x. Ну, если мы все равно полностью редизайним - то почему бы и не взять новую версию и использовать ее. Все равно будет полный прогон со стороны QA, в добавок - поменялся сам флоу созвона. Сказано - сделано, только насторожила запись:

Вроде разговор идет только про несовместимость Web SDK (у нас еще используется React Native SDK для мобильных устройств), но осадок остался.

На новый дизайн и сервер ушло где-то 3 - 4 дня (не люблю верстать, но что поделать). Настало время самого интересного - запуск процесса интервью. В итоге была взята Agora Web SDK 4.4.0. В течение следующего дня получилось сделать всю JS часть для созвона по видео и ауди (со всеми плюшками). За основу был взят пример из их же гитхаба (если что, то в архиве с самой либой лежат похожие примеры интеграции)

Еще через день все было уже на testing энвайронменте. Первые пол дня тестов прошли хорошо, на web портале все более-менее работало. Настало время проверки звонков с разных платформ (один человек с мобильного девайса - второй с сайта).

Первый звоночек

При звонке с мобилы на web, и наоборот - звонок не устанавливается. Проверили на проде тот же кейс - все огонь. Значит что-то пошло не так. Так как код на мобильных девайсах не менялся вообще (на их стороне изначально подумали над дизайном и все продумали) - значит проблема на моей стороне. Первое действие - нужно подписаться на все события от SDK что доступны - https://docs.agora.io/en/Voice/API%20Reference/web_ng/interfaces/iagorartcclient.html и смотреть что, где всплывает. Каково же было мое удивление, когда я увидел пустоту в консоле хромиума. Да это же не может быть, что бы Agora Web SDK 4.4.0 была не совместима с Agora React Native API 3.х!

После многих попыток, хоть как-то это дело завести - пришло "Принятие". Что поделать, придется брать все же Agora Web SDK 3.x.

Новый день начинается со скачивания последней версии (в рамках 3.x) и переделкой существующего функционала под другой SDK. К счастью, дело пошло быстро и за первую половину дня - все было готово. На локальной машине все работало отлично. Решил протестировать с коллегой по офису (он должен открыть ветку с прода и попробовать созвонится). И хоп, мы получаем ту же проблему - звонок не устанавливается, но что обнадеживает - в консоле проскакивают логи, что оппонент по звонку выходит из румы (в терминах агоры - это channel). Ну хоть какой прогресс, по сравнению с 4.x.

После первых двух часов дебага - было решено взять код с прода и попробовать его запустить. К черту текущее решение, просто берем код с прода, вcтавляем в HTML, пробрасываем пару конфигов и запускаем. О чудо, все работает. Все друг друга видят и слышат. Первая хорошая новость за день. Значит минорные версии 3.x совместимы между собой (это вселяет надежду с мобилами). Быстро подчищаем код с HTML и переносим его в JS модули. Запускаем и получаем дырку от бублика. Да что ж за день то сегодня такой. Откатываемся назад на вариант с кодом в HTML - работает. Ладно, теперь это уже личное...

Переносим "строчку за строчкой" из HTML в JS модули и почти каждый раз проверяем локально и с коллегой. Хм... Почему же оно все еще работает? Когда была перенесена последняя строчка, я очень удивился. Код был почти один-в-один как после миграции на 3.x, который я получил пол дня назад и он РАБОТАЛ. А давай-ка я попробую запустить старый свой вариант на 3.x. Оп-па не работает. Истина где-то рядом. Как хорошо что есть гит и можно сравнить. Отбросив различия в кодстайле я был очень удивлен увиденным:

Да не может же быть, что бы я так лоханулся. Быстро открываем документацию по либе (uid используется для подключения к руме). Нас интересует метод join:

Все! Я больше не могу. Поеду я домой, рабочий день уже давно закончен.

Второй звоночек

Новый день - новые силы. Как оказалось - на проде используется number, потому что со стороны мобил (с их слов) было жесткое требование на int и ничего более. Успокаиваемся и работаем... Проверяем локально, потом с коллегой, все хорошо - едем на testing. Проверяем web - хорошо, мобилы - черный экран у того кто остался на вебе, но звук работает отлично. Хоть какой прогресс...

После пары часы дебага и проверки различный гипотез, я был готов сдаться, но здесь произошло чудо. Разраб со стороны мобил говорит что у него все работает. После того, как мы созвонились, через один из мессенджеров, и расшарили экран - я действительно убедился, все условия соблюдены и оно действительно работает. Начали искать отличия. Мы с коллегой в офисе. QA на уделенке дома. Разработчик мобильной версии в Латвии. Просим QA пере-проверить кейс со звонком на разных платформа, только пусть звонит на мне в офис, а кому-то вне офиса. О-да, работает... Мы где-то близко...

Услышав наши "горячие" споры в комнате офиса, глава департамента встает и говорит: "Парни, а вы используете STUN / TURN сервера?". Такие слова я слышал впервые, поэтому пришлось гуглить.

В общем, все сошлись на том что для текущей версии проекта - никто не будет пока подключать STUN / TURN сервера (ибо если бесплатные STUN еще можно найти, то бесплатных TURN нет).

Почему не догадались, что из-за NAT в офисе - ловим проблемы? Да потому что звук работал. И видео на одной стороне работало отлично. А как раз черный экран в видео мы уже получали, когда ловили кейсы, где один клиент инициировал созвон по связке rtc/vp8, а второй live/h264.

Вот так и закончилось мое увлекательное приключение в мир WebRTC.

P.S. Если кто-то меня попросит еще раз сделать звонки на проекта - я первым делом пойду искать другую библиотеку.