Если Вы когда-нибудь собирались создать приложение для онлайн-конференции или внедрить в свое приложение звонки, то, вероятно, слышали о WebRTC. Но материалов об этой технологии на самом деле не очень много, и все, что есть, в основном направлено на разработчиков. Поэтому сегодня мы не будем углубляться в техническую часть, а постараемся в принципе понять, что такое WebRTC и, что видеосвязь – это на самом деле не магия. Надеюсь, эта статья поможет Вам получить представление, что же такое все-таки этот WebRTC.
Кратко о WebRTC
WebRTC (Web Real Time Communications) - это протокол, который описывает передачу потоковых аудио и видео данных в режиме реального времени. Он работает как с UDP, так и с TCP и может переключаться между ними. Один из главных плюсов этого протокола - это возможность соединять пользователей с помощью p2p (peer to peer) соединения, это значит, что медиапоток передается напрямую, минуя сервера. Но, чтобы использовать p2p, нужно учитывать его особенности, а также особенности самого протокола WebRTC.
STUN и TURN
Сети обычно проектируются с использованием частных IP адресов. Эти частные адреса используются внутри организации, чтобы устройства могли общаться локально, и они не маршрутизируются в интернете. Чтобы позволить устройству с приватным IP-адресом обращаться к устройствам и ресурсам за пределами локальной сети, приватный адрес сначала должен быть переведен в общедоступный публичный адрес. Переводом приватного адреса в публичный занимается NAT (Network Address Translation). NAT не является основной темой статьи, поэтому почитать подробнее предлагаю здесь. Нам лишь нужно знать, что в роутере есть таблица NAT и что, нам нужно, чтобы в NAT была создана специальная запись, которая пропускает к нашему клиенту пакеты. Чтобы создать запись в таблице NAT клиент должен что-то отправить удаленному клиенту, но проблема состоит в том, что ни один ни другой клиент не знают свои внешние IP адреса. Для решения этой проблемы были придуманы STUN и TURN сервера. Сразу стоит оговориться, что соединить двух клиентов можно и без STUN и TURN, но возможно это, только если клиенты находятся в одной сети.
Начнем со STUN сервера. STUN – это сервер, подключенный к интернету напрямую. Он получает пакет, в котором содержится внешний адрес клиента, отправившего этот пакет, и отправляет его обратно. Клиент узнает свой внешний адрес, а также порт, который нужен, чтобы роутер понимал, какой конкретно клиент отправил пакет, так как несколько клиентов из внутренней сети могут одновременно обратиться к внешней. Так в таблице NAT создается нужная нам запись.
TURN – это улучшенный STUN сервер, он может работать как STUN, но раз он существует, значит зачем-то он все-таки нужен. Существует несколько разновидностей NAT, некоторые из них запоминают не только внешний IP, но и порт STUN сервера, и не пропускают пакеты, пришедшие не со STUN сервера, получается, что NAT не будет пропускать пакеты, которые будет отправлять оппонент (удаленный клиент). Вот в таких случаях нужен TURN. Также, например, в 3g сетях невозможно установить p2p соединение, тогда TURN сервер становится ретранслятором, но клиенты думают, что общаются p2p.
Сигнальный сервер
Отлично, мы поняли, зачем нужны STUN и TURN сервера, но это не единственная особенность WebRTC. WebRTC не умеет передавать данные о соединении, это значит, что мы не сможем только с помощью WebRTC соединить клиентов. Нам нужно как-то настроить передачу данных о соединении, что конкретно это за данные и зачем они нужны, мы узнаем ниже. Для этого используется сигнальный сервер. Можно использовать любой способ передачи, главное, чтобы оппоненты могли обменяться данными между собой. В нашей компании, например, обычно используют вебсокеты.
Видеозвонок 1 на 1
Мы поговорили о STUN и TURN серверах, о том, зачем нужен сигнальный сервер. Но до сих пор не понятно, как же все-таки создать работающий звонок. Давайте теперь узнаем последовательность шагов, которые нужно выполнить, чтобы совершить видеозвонок.
Для начала скажем, что с помощью WebRTC Ваш iPhone может соединиться с любым устройством, не обязательно оба клиента должны общаться c iPhone, соединиться можно и с android-устройством, и с десктопным компьютером.
Имеем двух клиентов: инициатор звонка и ожидающий звонка.
Чтобы позвонить оппоненту, инициатор должен:
- Получить свой локальный медиапоток. Медиапоток – это поток видео и аудио данных. Каждый поток может состоять из нескольких медиатреков, при этом каждый медиатрек может состоять из нескольких медиаканалов.
Медиапотоков может быть несколько, например, поток с фронтальной камеры и поток с рабочего стола. Медиапоток синхронизирует медиатреки, но сами медиапотоки между собой не синхронизированы. Значит звук и видео с фронтальной камеры будут синхронизированы между собой, но не будут синхронизированы с видео рабочего стола. Медиаканалы внутри медиатрека тоже синхронизированы. Получение локального медиапотока в коде выглядит примерно так:
2. Сформировать offer, то есть предложить начать звонок
3. Передать свой SDP через сигнальный сервер. Что такое SDP? У устройства существует множество параметров, которые нужно учитывать для установления соединения, например, набор кодеков, с которыми может работать устройство. Все эти параметры формируются в объект SDP или дескриптор сессии, который пересылается оппоненту с помощью сигнального сервера. Важным замечанием является то, что локальный SDP хранится в виде текста и его можно редактировать самому перед отправкой через сигнальный сервер, например, чтобы принудительно выбрать кодек, но используется это очень редко и при этом не всегда может сработать.
4. Передать свои Ice Candidate через сигнальный сервер. Что такое Ice Candidate? SDP помогает установить логическое соединение, но физически клиенты пока не могут найти друг друга. Объекты Ice Candidate содержат информацию о нахождении клиента в сети, с помощью Ice Candidate клиенты смогут найти друг друга и начать передавать медиапоток. Стоит отметить, что локальный SDP генерируется только один, а объектов Ice Candidate много. Это нужно, потому что расположение клиента в сети может определяться внутренним IP-адресом, адресами TURN серверов, а также внешним адресом маршрутизатора, причем их может быть несколько. Поэтому чтобы определить расположение клиента в сети, нужно несколько объектов Ice Candidate.
5. Принять удаленный медиапоток (поток оппонента) и отобразить его. На iOS в качестве инструмента для рендеринга видеопотока можно использовать OpenGL или Metal.
Оппонент же в свою очередь должен выполнить в это же время те же шаги, за исключением второго, оппонент формирует answer, а не offer, то есть отвечает на звонок.
На самом деле answer и offer это одно и тоже, отличие состоит лишь в том, что когда ожидающий звонка формирует answer, то есть генерирует свой локальный SDP, он опирается на SDP объект инициатора звонка. Таким образом клиенты будут знать о параметрах устройства друг друга и, к примеру, смогут более корректно подобрать кодек.
Если кратко подытожить, то можно сказать так: клиенты сначала обмениваются SDP (устанавливают логическое соединение), а затем Ice Candidate (устанавливают физическое соединение). Таким образом клиенты успешно соединяются, видят друг друга, слышат друг друга и могут общаться.
Но это еще не все, что нужно учесть, когда работаешь с WebRTC в iOS. Если оставить все так, как есть сейчас, то пользователи приложения смогут успешно общаться, но только если будут находиться непосредственно в приложении, чтобы узнать о звонке и ответить на него, нужно чтобы приложение было открыто. Но эта проблема легко решается, в iOS существует такое понятие, как VoIP пуш, что это такое? Это один из видов пуш-уведомления в iOS, он создан как раз для того, чтобы работать со звонками.
Регистрируется он так:
С помощью этого пуш-уведомления можно отобразить экран входящего вызова, с помощью которого пользователь может либо принять, либо отклонить звонок. Делается это с помощью следующей функции:
И совершенно неважно, что пользователь делает в этот момент, играет в какую-нибудь игру или его телефон вообще заблокирован. VoIP пуш имеет самый высокий приоритет, это значит, что уведомления будут приходить всегда и пользователи смогут легко созваниваться друг с другом. При интеграции звонков, нужно всегда интегрировать VoIP пуш-уведомления, если Вы хотите, чтобы ими кто-то пользовался. Без VoIP звонками пользоваться очень сложно, потому что, чтобы звонок состоялся, нужно, чтобы юзеры сидели в приложении и ждали входящего вызова друг от друга. Это очень странно, в таком случае пользователи скорее выберут другое приложение.
Заключение
Мы поговорили о некоторых особенностях WebRTC, узнали, что необходимо учесть, для успешного соединения двух клиентов, узнали последовательность шагов, которые должны выполнить клиенты для того, чтобы звонок состоялся, а также, что еще нужно сделать помимо интеграции WebRTC, чтобы пользователи в iOS смогли созваниваться друг с другом. Надеюсь, что после прочтения этой статьи WebRTC для Вас уже не такое страшное и мистическое слово и что теперь Вы примерно понимаете, что Вам нужно, чтобы интегрировать WebRTC в свой продукт.
Комментарии