Spec-Zone.ru › Web APIs

Подключение WebRTC

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

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

Сигнальный канал

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

Информация, которую нам нужно обменять, — это Предложение и Ответ, которые содержат упоминаемый ниже SDP.

Узел A, который будет инициатором подключения, создаст Предложение. Затем он отправит это предложение узлу B через выбранный канал сигнализации. Узел B получит Предложение от канала сигнализации и создаст Ответ. Затем он отправит его обратно узлу A по каналу сигнализации.

Описание сессии

Конфигурация конечной точки в соединении WebRTC называется описанием сессии. Описание включает информацию о типе отправляемой медиа, её формате, используемом протоколе передачи, IP-адресе и порте конечной точки и другой информации, необходимой для описания конечной точки передачи медиа. Эта информация обменивается и хранится с использованием протокола описания сессии (SDP); если вам нужны подробности о формате данных SDP, вы можете найти их в RFC 8866.

Когда пользователь начинает вызов WebRTC другому пользователю, создаётся специальное описание, называемое предложением. Это описание включает всю информацию о предложенной конфигурации вызова со стороны звонящего. Получатель затем отвечает ответом, который является описанием его конца вызова. Таким образом, оба устройства обмениваются информацией, необходимой для обмена данными медиа. Этот обмен обрабатывается с использованием протокола установления интерактивного соединения (ICE), протокол, который позволяет двум устройствам использовать посредника для обмена предложениями и ответами, даже если эти два устройства разделены трансляцией сетевых адресов (NAT).

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

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

  1. Звонящий получает локальную Медиа через MediaDevices.getUserMedia
  2. Звонящий создаёт RTCPeerConnection и вызывает RTCPeerConnection.addTrack() (Поскольку addStream устаревает)
  3. Звонящий вызывает RTCPeerConnection.createOffer() для создания предложения.
  4. Звонящий вызывает RTCPeerConnection.setLocalDescription() для установки этого предложения в качестве локального описания (то есть описания локального конца подключения).
  5. После setLocalDescription() звонящий просит серверы STUN сгенерировать кандидатов ICE
  6. Звонящий использует сервер сигнализации для передачи предложения предполагаемому получателю вызова.
  7. Получатель получает предложение и вызывает RTCPeerConnection.setRemoteDescription() для записи его как удаленного описания (описания другого конца подключения).
  8. Получатель выполняет необходимую настройку для своей части вызова: получает свою локальную медиа и присоединяет каждую медиа-дорожку к соединению peer через RTCPeerConnection.addTrack()
  9. Затем получатель создаёт ответ, вызывая RTCPeerConnection.createAnswer().
  10. Получатель вызывает RTCPeerConnection.setLocalDescription(), передавая созданный ответ, чтобы установить ответ в качестве своего локального описания. Теперь получатель знает конфигурацию обоих концов подключения.
  11. Получатель использует сервер сигнализации для отправки ответа звонящему.
  12. Звонящий получает ответ.
  13. Звонящий вызывает RTCPeerConnection.setRemoteDescription() для установки ответа как удалённого описания для своего конца вызова. Теперь он знает конфигурацию обоих узлов. Медиа начинает передаваться в соответствии с конфигурацией.

Ожидаемые и текущие описания

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

Текущее описание (которое возвращается свойствами RTCPeerConnection.currentLocalDescription и RTCPeerConnection.currentRemoteDescription) представляет описание, которое в настоящее время фактически используется соединением. Это последнее соединение, с которым обе стороны полностью согласились.

Ожидаемое описание (возвращаемое RTCPeerConnection.pendingLocalDescription и RTCPeerConnection.pendingRemoteDescription) указывает на описание, которое в настоящее время рассматривается после вызова setLocalDescription() или setRemoteDescription(), соответственно.

При чтении описания (возвращаемого RTCPeerConnection.localDescription и RTCPeerConnection.remoteDescription) возвращаемое значение является значением pendingLocalDescription/pendingRemoteDescription, если есть ожидаемое описание (то есть, ожидаемое описание не null); в противном случае возвращается текущее описание (currentLocalDescription/currentRemoteDescription).

При изменении описания, вызвав setLocalDescription() или setRemoteDescription(), указанное описание устанавливается как ожидаемое описание, и слой WebRTC начинает оценивать, приемлемо ли оно. После согласования предложенного описания значение currentLocalDescription или currentRemoteDescription изменяется на ожидаемое описание, а ожидаемое описание снова устанавливается в null, что указывает на отсутствие ожидаемого описания.

Примечание: pendingLocalDescription содержит не только предложение или ответ, которые рассматриваются, но и любые локальные кандидаты ICE, которые были собраны с момента создания предложения или ответа. Аналогично, pendingRemoteDescription включает любые удалённые кандидаты ICE, которые были предоставлены вызовами RTCPeerConnection.addIceCandidate().

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

Кандидаты ICE

Помимо обмена информацией о медиа (обсуждалось выше в Предложении/Ответе и SDP), узлы должны обмениваться информацией о сетевом подключении. Это известно как кандидат ICE и детализирует доступные методы, которые узел может использовать для связи (прямо или через сервер TURN). Обычно каждый узел сначала предложит свои лучшие кандидаты, переходя к худшим кандидатам. В идеале кандидаты — UDP (поскольку это быстрее, а потоки медиа способны восстанавливаться после прерываний относительно легко), но стандарт ICE также допускает кандидатов TCP.

Примечание: Как правило, кандидаты ICE, использующие TCP, будут использоваться только тогда, когда UDP недоступен или ограничен таким образом, что делает его непригодным для потоковой передачи медиа. Однако не все браузеры поддерживают ICE через TCP.

ICE позволяет кандидатам представлять подключения либо через TCP, либо через UDP, при этом UDP, как правило, предпочтительнее (и более широко поддерживается). Каждый протокол поддерживает несколько типов кандидатов, причём типы кандидатов определяют, как данные передаются от узла к узлу.

Типы кандидатов UDP

Кандидаты UDP (кандидаты с их protocol установленным в udp) могут быть одного из этих типов:

host

Кандидат хоста — это кандидат, для которого его ip адрес является фактическим прямым IP-адресом удалённого узла.

prflx

Кандидат peer-рефлексивный — это кандидат, чей IP-адрес получен из симметричного NAT между двумя узлами, обычно как дополнительный кандидат во время протокола ICE-стримлирования (то есть дополнительный обмен кандидатами, который происходит после основной сигнализации, но до завершения фазы проверки подключения).

srflx

Сервер-рефлексивный кандидат генерируется сервером STUN/TURN; инициатор подключения запрашивает кандидата у сервера STUN, который пересылает запрос через NAT удалённого узла, который создаёт и возвращает кандидата с IP-адресом, локальным для удалённого узла. Затем сервер STUN отвечает на запрос инициатора с кандидатом, чей IP-адрес не связан с удалённым узлом.

relay

Кандидат реле генерируется аналогично сервер-рефлексивному кандидату ("srflx"), но используя TURN вместо STUN.

END_OF_DOCUMENT_MARKER

Типы кандидатов TCP

Кандидаты TCP (то есть кандидаты, у которых protocol является tcp) могут быть следующих типов:

active

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

passive

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

so

Транспорт попытается одновременно открыть соединение со своим партнёром.

Выбор пары кандидатов

Уровень ICE выбирает одного из двух партнёров в качестве управляющего агента. Это агент ICE, который принимает окончательное решение о том, какую пару кандидатов использовать для соединения. Другой партнёр называется управляемым агентом. Вы можете определить, какой конец соединения является вашим, проверив значение RTCIceCandidate.transport.role, хотя в общем случае это не имеет значения.

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

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

После завершения сессии ICE конфигурация, которая сейчас активна, является окончательной, если не происходит сброс ICE.

В конце каждого поколения кандидатов отправляется уведомление об окончании кандидатов в виде RTCIceCandidate, у которого свойство candidate является пустой строкой. Этот кандидат всё равно должен быть добавлен к соединению с помощью метода addIceCandidate(), как обычно, чтобы передать это уведомление удалённому партнёру.

Когда больше не ожидается никаких кандидатов во время текущего обмена по переговорам, уведомление об окончании кандидатов отправляется путём передачи RTCIceCandidate, у которого свойство candidate является null. Это сообщение не нужно отправлять удалённому партнёру. Это устаревшее уведомление о состоянии, которое можно обнаружить, наблюдая за изменением iceGatheringState на complete, наблюдая за событием icegatheringstatechange.

Когда возникают проблемы

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

Откаты ICE

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

Вместо этого вы можете инициировать откат ICE. Откат восстанавливает предложение SDP (и конфигурацию соединения, соответственно) до конфигурации, которая была в последний раз, когда состояние соединения signalingState было stable.

Для программной инициации отката отправьте описание, у которого type является rollback. Любые другие свойства в объекте описания игнорируются.

Кроме того, агент ICE автоматически инициирует откат, когда партнёр, который ранее создал предложение, получает предложение от удалённого партнёра. Другими словами, если локальный партнёр находится в состоянии have-local-offer, что указывает на то, что локальный партнёр ранее отправлял предложение, вызов setRemoteDescription() с полученным предложением инициирует откат, так что переговоры переключаются с удалённого партнёра как инициатора на локального партнёра как инициатора.

Перезапуски ICE

Узнайте о процессе перезапуска ICE.

Весь обмен в сложном диаграмме

A complete architectural diagram showing the whole WebRTC process.

Оригинальный источник

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Connectivity

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API