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

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

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

Что такое Предложение/Ответ и Канал сигнализации?

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

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

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

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

Конфигурация конечной точки WebRTC-соединения называется "описание сессии"(session description). Описание включает информацию о типе посылаемого медиа, его формате, используемом протоколе передачи, IP-адресе и порте конечной точки, и другую информацию, необходимую для описания конечной точки передачи медиа. Эта информация обменивается и хранится с помощью "протокола описания сессии". Session Description Protocol(SDP). Если вы хотите подробную информацию о формате данных SDP, вы можете найти её в RFC 2327.

Когда пользователь запускает WebRTC вызов другого пользователя, создаётся специальное описание, называемое "предложение"(offer). Это описание включает всю информацию для соединения, о предлагаемой конфигурации вызывающего абонента. Получатель затем откликается "ответом"(answer), являющимся описанием его конца соединения. Таким образом, оба устройства разделяют друг с другом информацию, необходимую для того, чтобы обмениваться медиа данными. Этот обмен обрабатывается с помощью "интерактивного создания подключения". Interactive Connectivity EstablishmentICE (en-US). ICE - протокол, который позволяет двум устройствам использовать посредника для обмена "предложениями"(offers) и "ответами"(answers), даже если эти два устройства разделены механизмом "преобразования сетевых адресов". (NAT (en-US)(Network Address Translation).

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

Процесс "предложение/ответ"(offer/answer) выполняется как, когда соединение впервые устанавливается, так и в любой момент, когда формат соединения или другая конфигурация нуждается в изменении. Независимо от того, является ли это новым соединением, или реконфигурированием существующего, это основные шаги, которые должны произойти для обмена "предложением"(offer) и "ответом"(answer). Пропустим ICE-слой на данный момент:

  1. Вызывающий вызывает RTCPeerConnection.createOffer() (en-US) для создания "предложения"(offer)
  2. Вызывающий вызывает RTCPeerConnection.setLocalDescription() (en-US) для установки этого "предложения" как локального описания (то есть описания локального конца соединения).
  3. Вызывающий использует сигнальный сервер для передачи "предложения" к требуемому получателю вызова.
  4. Получатель получает "предложение" и вызывает RTCPeerConnection.setRemoteDescription() (en-US) для записи его, как удалённого описания(описания другого конца соединения).
  5. Получатель делает всякую настройку, которую должен сделать для его конца соединения, включая добавления исходящих потоков для соединения.
  6. Получатель затем создаёт "ответ"(answer) посредством вызова RTCPeerConnection.createAnswer() (en-US).
  7. Получатель вызывает RTCPeerConnection.setLocalDescription() (en-US), чтобы установить "ответ"(answer) в качестве локального описания. Получатель теперь знает конфигурацию обоих концов соединения.
  8. Получатель использует сигнальный сервер для отправки "ответа"(answer) вызывающему.
  9. Вызывающий получает "ответ"(answer).
  10. Вызывающий вызывает RTCPeerConnection.setRemoteDescription() (en-US) для установки "ответа"(answer) как удалённого описания для его конца соединения. Теперь известна конфигурация обоих узлов. Медиа начинает течь в соответствии с настройками.

Рассматриваемые и текущие описания

Спускаясь на один шаг глубже в процесс, мы находим, что localDescription и remoteDescription, свойства, возвращаемые эти двумя описаниями, не так просты, как выглядят. Потому что во время повторных переговоров(перезаключения) (renegotiation), "предложение"(offer) может быть отклонено, поскольку оно предлагает несовместимый формат. Необходимо, чтобы каждая конечная точка имела возможность предложить новый формат, но не переключаться на него, пока он не принят другим узлом. По этой причине, WebRTC использует "рассматриваемые" и "текущие" "описания".

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

"Рассматриваемое описание"(pending description) (возвращаемое RTCPeerConnection.pendingLocalDescription (en-US) и RTCPeerConnection.pendingRemoteDescription (en-US)) указывает на то описание, которое в настоящий момент находится на рассмотрении после вызова setLocalDescription() или setRemoteDescription(), соответственно.

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

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

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

Смотрите отдельные статьи по этим свойствам и методам для большей конкретики.

Что такое ICE-кандидат?

В дополнение к обмену информацией о медиа(обсуждённой выше в offer/answer и SDP), узлы должны обменяться информацией о сетевом соединении. Об этом известно как о ICE-кандидате и деталях доступных методов, которыми узел может общаться (непосредственно или через TURN-сервер).

Весь обмен в сложной схеме

A complete architectural diagram showing the whole WebRTC process.