Жизнь WebRTC-сессии

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

Эта статья не вдаётся в детали фактически использованных API в установке и обработке WebRTC-соединения. Это просто обзор процесса в целом с некоторой информацией о том, для чего нужен каждый шаг. Смотрите статью Signaling and video calling, чтобы получить пример с пошаговым объяснением того, что делает код.

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

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

Установка соединения

Интернет большой. Реально большой. Умные люди, несколько лет назад, заметив то, насколько он велик, каким большим он может стать и то как быстро растёт, а также ограничения 32-битной системы адресации протокола IP, и поняли, что нужно начать что-то делать, чтобы создать новую 64-битную систему адресации. Но в какой-то момент они так же пришли к выводу, что переход на новую систему займёт больше времени, чем продержатся 32-разрядные адреса. Затем другие умные люди придумали способ, позволяющий нескольким компьютерам использовать один и тот же 32-итный IP-адрес. Network Address Translation (NAT (en-US)) - это стандарт, который поддерживает разделение адреса путём маршрутизации входящих и исходящих пакетов данных в и из локальной сети (LAN), которые разделяют единственный WAN (глобальный) адрес.

Проблемой для пользователя является то, что каждый отдельный компьютер в сети Интернет не обязан иметь уникальный IP-адрес, и по сути, IP-адрес устройства может измениться не только тогда, когда оно перемещается из одной сети в другую, но и если их сетевой адрес был изменён NAT (en-US) и/или DHCP. Для разработчиков, пытающихся строить одноранговые сети, эта ситуация является хорошей головоломкой: без уникального идентификатора для каждого устройства, нет возможности моментально автоматически выяснить то, как подключиться к конкретному устройству в Интернет. Если вызнаете, с кем вы хотите поговорить, вам не обязательно знать, какой адрес у вашего собеседника.

Это похоже на попытку отправить письмо подруге Мишель, написав только на конверте слово "Мишель" и опустить в почтовый ящик. Вам необходимо выяснить её адрес и указать его на конверте, иначе она сильно удивится, почему вы забыли про её день рождения.

Всё это входит в процесс сигнализации.

Процесс Сигнализации

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

Вы можете задаться вопросом, почему нечто основоположное для процесса установки WebRTC-соединения вынесено из спецификации? Ответ прост: потому как два устройства не могут контактировать друг с другом, и спецификация не может предусмотреть все возможные способы использования WebRTC, также это приобретает ещё больший смысл с точки зрения предоставления разработчику возможности выбора наиболее подходящей сетевой технологии и протоколов передачи сообщений.

Для обмена сигнальной информацией, вы можете выбрать отправку JSON-объектов через WebSocket-соединение, можете использовать протокол XMPP/SIP через соответствующий канал, так же можете использовать XMLHttpRequest через HTTPS с техникой пуллинга (HTTPS with polling), или же другие комбинации технологий, которые вам могут прийти в голову. Вы даже можете использовать электронную почту в качестве сигнального канала.

Стоит также отметить, что сигнальный канал может вообще находиться вне компьютерной сети. Один узел может выпустить объект данных, который затем может быть распечатан на принтере, физически перемещается (пешком или голубиной почтой) до другого устройства, данные вводятся в устройство, ответ устройства затем возвращается обратно, так же пешком, и так далее, пока WebRTC-соединение между узлами открыто. В этом случае, будет очень высокая латентность, но этот сценарий возможен.

Обмен информации во время процесса сигнализации

Существует три основных типа информации, которой нужно обмениваться во время процесса сигнализации:

  • Управляющие сообщения, используемые для настройки, открытия и закрытия каналов коммуникации, а также для обработки ошибок
  • Информация, необходимая для того, чтобы настроить соединение: информация об IP-адресе и порте необходима узлам, чтобы они могли разговаривать друг с другом.
  • Необходимо согласовать медиа-потоки: какие могут использоваться между узлами кодеки и форматы медиа-данных? Все это необходимо согласовать до того, как будет установлена WebRTC-сессия.

Только после успешного завершения процесса сигнализации, может быть возможен процесс открытия WebRTC-соединения между узлами.

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

Процесс сигнализации

Существует последовательность действий, которую нужно выполнить, чтобы стало возможным начало WebRTC-сессии:

  1. Каждый узел создаёт объект RTCPeerConnection, представляющий собой WebRTC-сессию и сохраняющийся до её завершения.
  2. Каждый узел устанавливает обработчик события icecandidate,которая занимается отправкой этих кандидатов в другую сторону по каналу сигнализации.
  3. Каждый узел устанавливает обработчик события addstream, которое срабатывает когда начинает приходить поток данных от удалённого узла. Этот обработчик должен подключить этот поток к потребителю, например к элементу <video>.
  4. Вызывающий узел создаёт уникальный идентификатор, токен или нечто, что сможет идентифицировать вызов на сигнальном сервере, и обмениваться с принимающим узлом. Форма и содержимое идентификатора остаётся на усмотрение разработчика.
  5. Каждый узел подключается к согласованному сигнальному серверу, такому например как известный обоим WebSocket-сервер, для обмена сообщениями.
  6. Каждый узел сообщает сигнальному серверу, что хочет подключиться к одной и той же WebRTC-сессии (идентифицируемой токеном, определённым на шаге 4)
  7. descriptions, candidates, etc. — more coming up

Перезапуск сессии ICE агент

Иногда, во время срока службы WebRTC сессии, сетевые условия изменяются. Один из пользователей, возможно, перейдёт от сотовой сети к сети WiFi или сеть может стать перегруженной. Например: когда это произойдёт, ICE агент может перезапустить сессию. Это процесс, с помощью которого сетевое соединение перезапустится и восстановится, точно таким же образом выполняется начальная установка сессии, за одним исключением того пока не установится новая сессия. Тогда сессия сменяется и переходит к новому сетевому соединению, а старое соединение закрывается.

Примечание: Различные браузеры поддерживают перезапуск сессии при разных условиях. Не все браузеры будут выполнять перезапуск сессии из-за перегрузки сети, например:

Есть два уровня перезапуска сессии: полная перезагрузка сессии вызывает все мультимедийные потоки в сеансе и должны быть пересмотрены. Частичная перезагрузка сессии позволяет агенту сессии перезапустить конкретный медиапоток вместо того, чтобы перезапускать все медиаданные. Некоторые браузеры пока не поддерживают частичную перезагрузку сессии, однако. <<< Все зависит от вашего кодерства... >>>

Если вам необходимо изменить конфигурацию соединения каким-либо образом (например, изменение к другому набору связи), вы можете сделать это перед RTCPeerConnection.setConfiguration()(перед назначением конфигурации) с обновлённой RTCConfiguration(конфигурацией) перед повторным запуском движка.

Чтобы явно вызвать перезапуск сессии, нужно начать переговорный процесс с помощью вызова RTCPeerConnection.createOffer(), указав параметр iceRestart(перезапуск сессии) со значением истины(true). Затем обработать процесс соединения так, как вы это обычно делаете.

Transmission

getUserMedia

LocalMediaStream object

Reception