turn server что это

Turn server что это

Обновлено 29 апреля 2020

Введение

TURN (Traversal Using Relay NAT) — это протокол, который позволяет узлу за NAT или брандмауэром получать входящие данные через TCP или UDP соединения. Такая возможность особенно актуальна для узлов позади симметричных NAT, или брандмауэров, которые собираются стать принимающей стороной в соединении с одним конкретным узлом (peer-ом).

TURN сервер – это улучшенный STUN сервер, поэтому любой TURN сервер может работать и как STUN сервер. (Session Traversal Utilities for NAT) — это сетевой протокол, который позволяет клиенту, находящемуся за сервером трансляции адресов (или за несколькими такими серверами), определить свой внешний IP-адрес, способ трансляции адреса и порты во внешней сети, связанный с определённым внутренним номером порта. Эта информация используется для установления соединения UDP между двумя хостами в случае, если они оба находятся за маршрутизатором NAT.

TURN сервер используется в крайнем случае, как посредник (relay), превращая p2p в клиент-сервер-клиентную связь, там где прямая связь невозможна. WebRTC успешно справляется с такими проблемами, используя протокол ICE, который, правда, требует использования дополнительных серверов (STUN, TURN). – технология, ориентированная на браузеры, которая позволяет соединить два клиента для видео-передачи данных. Основные особенности – внутренняя поддержка браузерами и способность соединять клиентов без использования дополнительных серверов – соединение peer-to-peer (p2p).

Подготовка LXC контейнера

Мы рекомендуем выполнить установку TURN сервера в отдельном контейнере, настроив его согласно инструкции.

Источник

WebRTC: фреймворк ICE, STUN и сервера TURN

WebRTC (Web Real Time Communication) — это проект с открытым исходным кодом, позволяющий создавать одноранговые (P2P) аудио- и видеосвязи через JavaScript API.

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

Это не так просто, как кажется. Устройства пользователей обычно не имеют публичного IP-адреса или могут быть не допущены до установления какого-либо прямого соединения. Вот почему нам нужна платформа Interactive Connectivity Establishment (ICE).

Если бы два пользователя совершали телефонный звонок, то один должен был бы только набрать номер телефона другого, а другой должен был бы только принять звонок. Каждый телефонный номер соответствует только одному устройству, а их вполне достаточно, чтобы обеспечить прямое соединение.

С другой стороны, в Интернете исторически не хватало “номеров” для каждого подключенного устройства. С IPv4 было доступно только около 4 миллиардов адресов. Недостаток адресов был решен путем группировки многих устройств под одним общим адресом с маршрутизатором, переводящим адреса в пакеты, проходящие через него. Этот процесс называется трансляцией сетевых адресов (NAT).

Существуют различные типы NAT, но некоторые из них выделяют публичный IP-адрес и порт для потоков UDP (то, что нам нужно). Поэтому, когда нужно создать P2P-соединение с одноранговым узлом, первая задача состоит в том, чтобы выяснить, за каким типом NAT вы находитесь, и если он есть, получить IP-адрес и порт, который сможете дать своему контакту.

В этом поможет протокол STUN (Session Traversal Utilities for NAT). Необходимо предоставить сервер STUN при попытке установить P2P-соединение. В WebRTC вы предоставляете его при создании объекта JavaScript, представляющего соединение:

Чтобы определить, находитесь ли вы за NAT, и получить публичный IP-адрес, если это возможно, агент ICE отправит запрос на указанный вами сервер STUN. Если NAT есть, он установит свой публичный адрес и порт в заголовке сообщения. Сервер STUN попытается пинговать этот публичный адрес с разных IP-адресов, чтобы проверить, находитесь ли вы за NAT, и если да, то какой это тип. Если все пойдет правильно, то сервер STUN вернет адрес и порт.

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

Реализации NAT

Не все NAT реализованы одинаково и могут отличаться в том, как они позволяют пакетам проходить. Некоторые реализации NAT, такие как NAT один к одному, позволят установить P2P-соединение. Некоторые, например симметричные, этого не делают.

NAT один к одному (или Full Cone NAT)

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

Если за таким NAT стоят одноранговые узлы, то для установления P2P-соединения достаточно получить публичный IP-адрес и порт обоих одноранговых узлов.

Симметричный NAT

В симметричных NAT’ах внешний IP-адрес/порт зависит от внутреннего IP-адреса/порта duo и назначения. Запросы от 198.145.1.2: 3000 к серверу TURN сопоставляются с заданным IP-адресом и портом внешнего источника. Но если один и тот же внутренний хост отправляет пакет в другое место назначения, например в одноранговый узел, с которым он пытается связаться, внешний IP-адрес/порт будет отличаться. Кроме того, внешний хост должен получить пакет от внутреннего хоста, прежде чем он сможет отправить пакет обратно.

Если контакты находятся за симметричным NAT, они не смогут общаться. Вот почему нам нужно другое решение: TURN.

Когда прямое соединение не может быть установлено, связь должна проходить через сервер TURN. TURN обозначает “Traversal Using Relays around NAT”. Как следует из названия, соединение будет проходить через ретрансляционный сервер.

Это очевидно ухудшает производительность и имеет финансовые издержки. В то время как сервер STUN имеет дело с очень маленькими и легкими запросами, сервер TURN ретранслирует весь разговор, что генерирует гораздо больше трафика. Вот почему вы можете найти публичные серверы STUN, но не публичные серверы TURN (по крайней мере, ни один владелец которых не знает, что он является публичным).

ICE в WebRTC

Чтобы быть установленным в TURN, для WebRTConnection нужно указать URL-адрес вашего сервера в объекте RCTPeerConnection:

Серверы TURN по причине, описанной выше, обычно защищены паролем.

Агент ICE сначала попытается установить соединение непосредственно между одноранговыми узлами и переключится на опцию TURN только в том случае, если это не сработает. Вам не нужно заботиться об этом самостоятельно, нужно только слушать событие onicecandidate RTCPeerConnection. Оно будет срабатывать каждый раз, когда обнаруживается кандидат ICE. Затем вам нужно отправить кандидата своему контакту через свой сигнальный механизм:

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

Источник

WebRTC: фреймворк ICE, STUN и сервера TURN

Sep 11, 2020 · 4 min read

WebRTC (Web Real Time Communication) — это проект с открытым исходным кодом, позволяющий создавать одноранговые (P2P) аудио- и видеосвязи через JavaScript API.

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

Это не так просто, как ка ж ется. Устройства пользователей обычно не имеют публичного IP-адреса или могут быть не допущены до установления какого-либо прямого соединения. Вот почему нам нужна платформа Interactive Connectivity Establishment (ICE).

Если бы два пользователя совершали телефонный звонок, то один должен был бы только набрать номер телефона другого, а другой должен был бы только принять звонок. Каждый телефонный номер соответствует только одному устройству, а их вполне достаточно, чтобы обеспечить прямое соединение.

Читайте также:  Что такое курьерская доставка ems

С другой стороны, в Интернете исторически не хватало “номеров” для каждого подключенного устройства. С IPv4 было доступно только около 4 миллиардов адресов. Недостаток адресов был решен путем группировки многих устройств под одним общим адресом с маршрутизатором, переводящим адреса в пакеты, проходящие через него. Этот процесс называется трансляцией сетевых адресов (NAT).

Существуют различные типы NAT, но некоторые из них выделяют публичный IP-адрес и порт для потоков UDP (то, что нам нужно). Поэтому, когда нужно создать P2P-соединение с одноранговым узлом, первая задача состоит в том, чтобы выяснить, за каким типом NAT вы находитесь, и если он есть, получить IP-адрес и порт, который сможете дать своему контакту.

В этом поможет протокол STUN (Session Traversal Utilities for NAT). Необходимо предоставить сервер STUN при попытке установить P2P-соединение. В WebRTC вы предоставляете его при создании объекта JavaScript, представляющего соединение:

Чтобы определить, находитесь ли вы за NAT, и получить публичный IP-адрес, если это возможно, агент ICE отправит запрос на указанный вами сервер STUN. Если NAT есть, он установит свой публичный адрес и порт в заголовке сообщения. Сервер STUN попытается пинговать этот публичный адрес с разных IP-адресов, чтобы проверить, находитесь ли вы за NAT, и если да, то какой это тип. Если все пойдет правильно, то сервер STUN вернет адрес и порт.

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

Реализации NAT

Не все NAT реализованы одинаково и могут отличаться в том, как они позволяют пакетам проходить. Некоторые реализации NAT, такие как NAT один к одному, позволят установить P2P-соединение. Некоторые, например симметричные, этого не делают.

NAT один к одному (или Full Cone NAT)

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

Если за таким NAT стоят одноранговые узлы, то для установления P2P-соединения достаточно получить публичный IP-адрес и порт обоих одноранговых узлов.

Симметричный NAT

В симметричных NAT’ах внешний IP-адрес/порт зависит от внутреннего IP-адреса/порта duo и назначения. Запросы от 198.145.1.2: 3000 к серверу TURN сопоставляются с заданным IP-адресом и портом внешнего источника. Но если один и тот же внутренний хост отправляет пакет в другое место назначения, например в одноранговый узел, с которым он пытается связаться, внешний IP-адрес/порт будет отличаться. Кроме того, внешний хост должен получить пакет от внутреннего хоста, прежде чем он сможет отправить пакет обратно.

Если контакты находятся за симметричным NAT, они не смогут общаться. Вот почему нам нужно другое решение: TURN.

Когда прямое соединение не может быть установлено, связь должна проходить через сервер TURN. TURN обозначает “Traversal Using Relays around NAT”. Как следует из названия, соединение будет проходить через ретрансляционный сервер.

Это очевидно ухудшает производительность и имеет финансовые издержки. В то время как сервер STUN имеет дело с очень маленькими и легкими запросами, сервер TURN ретранслирует весь разговор, что генерирует гораздо больше трафика. Вот почему вы можете найти публичные серверы STUN, но не публичные серверы TURN (по крайней мере, ни один владелец которых не знает, что он является публичным).

ICE в WebRTC

Чтобы быть установленным в TURN, для WebRTConnection нужно указать URL-адрес вашего сервера в объекте RCTPeerConnection:

Серверы TURN по причине, описанной выше, обычно защищены паролем.

Агент ICE сначала попытается установить соединение непосредственно между одноранговыми узлами и переключится на опцию TURN только в том случае, если это не сработает. Вам не нужно заботиться об этом самостоятельно, нужно только слушать событие onicecandidate RTCPeerConnection. Оно будет срабатывать каждый раз, когда обнаруживается кандидат ICE. Затем вам нужно отправить кандидата своему контакту через свой сигнальный механизм:

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

Источник

WebRTC для любопытных (часть 1)

Книга довольно поверхностно объясняет как работает WebRTC «под капотом», для подробностей надо читать RFC. Ссылки на RFC различных используемых протоколов буду приводить. Стоит особо отметить главу «Отладка», где неплохо описываются идеи того, как отлаживать различные проблемы с сетью, задержками и прочим.

Что такое Webrtc?

Помимо JavaScript протокол WebRTC реализован также и на других языках програмирования. Можно найти множество реализаций серверов, библиотек, реализующих протокол, примером может стать реализация на go: github.com/pion/webrtc. Пишется реализация и на rust: https://github.com/webrtc-rs/webrtc (проект довольно интересный, потому что это переписываение pion/webrtc на rust).

Протокол WebRTC поддерживается в IETF в группе rtcweb. API WebRTC задокументировано в W3C как webrtc-pc.

Приемущества WebRTC

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

Итак, приемущества WebRTC:

Множество различных реализаций

Можно работать прямо из браузера

Перепрофилированная существующая технология, то есть не изобретали колес, когда делали WebRTC

Контроль за перегруженностью

Задержка (latency, имеется в виду задержка аудио и/или видеопотока) в пределах 1 секунды

WebRTC это набор разных технологий

Это тема, для объяснения которой потребуется целая книга. Для начала разобъем ее на четыре части:

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

Интересный факт в WebRTC это то, что каждый шаг использует множество других протоколов!

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

Сигналинг или как агенты находят друг друга в сети

Когда запускается WebRTC-агент, он не знает с кем ему соединиться, и какого рода информацией он будет обмениваться. Сигналинг (Signaling) решает эту проблему! Сигналинг нужен для того, чтобы два агента могли найти и вызвать друг друга в сети перед тем, как начать обмен информацией.

Сигналинг использует существующий протокол SDP (Session Description Protocol). SDP это простой текстовый протокол. Каждое SDP-сообщение состоит из пар ключ-значение, расположенных в строгом порядке (rfc4566), которые в свою очередь составляют набор медиа-секций. SDP-сообщения, которыми обмениваются WebRTC-агенты содержит такую информацию как:

адреса IP и порты агентов, по которым можно соединиться с агентом (это т.н. ICE-кандидаты)

сколько аудио и видео треков агент желает отправить

какие аудио и видео кодеки поддерживает каждый из агентов

значения используемые во время соединения ( uFrag / uPwd ).

значения используемые для безопасности (отпечаток сертификата)

Отметим, что сигналинг обычно работает как бы в сторонке; то есть приложения не используют WebRTC для обмена SDP сообщениями. Тут подходит любой способ обмена этими сообщениями: REST, Websocket, да хоть письмом по почте можно отправить другому пиру SDP-сообщение, а тот в свою очередь отправит свое. В своем приложении для тестов я вообще использовал firebase для сигналинга.

Установка соединения и NAT Traversal с помощью STUN/TURN

Теперь у обоих сторон WebRTC агентов достаточно информации о том, чтобы соединиться друг с другом. Далее используется другая устоявшаяся технология под названием ICE.

Настоящая магия здесь это т.н. NAT Traversal и STUN/TURN сервера. Обе эти концепции необходимы для соединения с ICE агентом из другой сетки. Далее мы изучим этот вопрос глубже.

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

Шифрование передачи информации с помощью DTLS и SRTP

Для видео/аудио в WebRTC используется другой протокол: RTP. Для шифрования RTP-пакетов используется протокол SRTP. SRTP сессия инициализируется с помощью ключей шифрования полученных в ходе DTLS сессии (rfc5764). Далее мы обсудим, почему для медиа-данных используется свой собственный протокол.

Читайте также:  Что такое липиды простыми словами

Теперь все готово! У нас есть двунаправленный и безопасный канал. Если у вас стабильное соединение между вашими WebRTC-агентами, то вышеописанный комплекс процедур достаточен чтобы начать им (агентам) общаться. Однако в жизни все не так идеально, как кажется: мы постоянно будем сталкиваться с потерей пакетов в сети, ограниченной пропускной способностью сети. Дальше мы подумаем, как справляться со всеми этими проблемами.

Общение между пирами через RTP и SCTP

Сейчас мы имеем два WebRTC-агента с безопасным двунаправленным соединением. Давайте начнем взаимодействие! И снова мы используем уже существующие протоколы: RTP (Real-time Transport Protocol), и SCTP (Stream Control Transmission Protocol). Используйте RTP для обмена аудио/видео шифрованным по протоколу SRTP и SCTP для обмена DataChannel-сообщениями, шифрованными с помощью DTLS.

RTP сам по себе очень минимален, но предоставляет все необходимое для стриминга в реальном времени. Важно то, что RTP предоставляет разработчику гибкость в управлении потерями пакетов, задержками и перегрузками так, как он (разработчик) пожелает. Далее мы будем обсуждать по этой теме в части про медиа.

WebRTC это набор протоколов

Рис.1. WebRTC Agent Diagram

Кратко: как работает WebRTC (API)

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

Метод addTrack создает новый RTP-поток. Для потока генерируется случайный Synchronization Source (SSRC). Созданный RTP поток будет затем описан в Session Description-сообщении внутри медиа-секции после вызова createOffer метода. Каждый вызов addTrack создает новый SSRC и добавляет медиа-секцию в SDP-сообщение.

Сразу после того, как SRTP сессия установлена, зашифрованные медиа-пакеты начнут отправляеться через ICE.

createDataChannel создает новый SCTP-поток, если еще не был добавлен. По умолчанию SCTP выключен, но инициализируется как только одна из сторон потребует data channel.

Сразу после того, как DTLS сессия установлена, SCTP пакеты начнут отправляться через ICE.

createOffer генерирует Session Description для отправки удаленному пиру.

Вызов createOffer ничего не меняет на локальном пире.

После вызова setLocalDescription сгенерированное SDP-сообщение также отправляется на удаленный пир (выше обусждалось, что это можно делать любым способом), и далее на удаленном пире SDP-сообщение (offer) передается в метод setRemoteDescription. Удаленный пир в свою очередь отправляет свой локальный SDP в ответ (answer), который также нужно передать локально в setRemoteDescription.

addIceCandidate позволяет WebRTC-агенту добавить больше удаленных ICE-кандидатов.

В следующей части разберем Signaling и SDP.

Источник

Как отлаживать WebRTC

В Voximplant мы используем WebRTC с момента ее появления: сначала как альтернативу Flash для голосовых и видеозвонков, а затем как полную замену. Технология прошла долгий и болезненный путь развития, только недавно ее стали поддерживать все основные браузеры, есть сложности с передачей экрана, нескольких видеопотоков, а иногда браузер падает просто если выключить и включить видеопоток. Накопленный опыт позволяет переводить для Хабра интересные статьи, и сегодня мы передаем слово Ли Сильвестру из Xirsys, который расскажет про отладку (видео)звонков в Chrome, Firefox, Safari и Edge. Отлаживать WebRTC непросто, у нас даже есть специальные инструкции по снятию логов в популярных браузерах. А что есть у Ли – вы узнаете под катом (спойлер: много всего, включая WireShark).

Темная сторона WebRTC

Работая в Xirsys, я видел несколько действительно крутых приложений, которые использовали WebRTC. Но пока небольшая группа разработчиков создает высокотехнологичные штуки, большая часть программистов не могут даже начать использовать WebRTC. Почему? А все просто. Оно сложное.

Многим из нас знакомо типичное веб-приложение. У такого приложения есть клиент, который отправляет запросы и сервер, который на эти запросы отвечает. Простой, линейный и легко предсказуемый процесс. Если что-то пойдет не так, мы обычно знаем где смотреть логи и что могло случиться. А вот с WebRTC все не так просто.

Асинхронность

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

WebRTC асинхронно по своей природе. И это совсем не простенькая асинхронность AJAX. Если проводить аналогию, то это несколько одновременно запущенных AJAX запросов, которые пытаются согласовать данные на двух компьютерах. То еще развлечение.

Минное поле обхода NAT

Создание веб-приложений сводится к разработке чего-то, что запускается на сервере и отвечает на запросы. Самое страшное что может случиться — это не открытый в IPTables порт. Лечится за 2 минуты. Чего не скажешь о WebRTC.

Веб-серверы, даже не их софт, а железо — это устройства с публичными IP-адресами. Они сделаны, чтобы быть доступными откуда угодно. А WebRTC сделано, чтобы отправлять и принимать данные с компьютеров пользователей. Которые обычно имеют IP-адреса 192.168.что-нибудь и не горят желанием отвечать на сетевые запросы.

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

Где начинать отладку

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

Как WebRTC устанавливает подключение

Все подключения WebRTC требуют «небольшой помощи» со стороны сигнального протокола. «Небольшая помощь» — это ваш собственный сервер и протокол, с помощью которого звонящий сможет пообщаться с тем, кому звонит, прежде чем установить Peer-to-peer подключение.

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

Обычно используется протокол COMET (или SIP — примечание переводчика) и веб-сокеты. WebRTC ничем не ограничивает разработчиков, так что можно использовать что нравится, хоть передавать данные через Notepad и копипасту (делали на одном из воркшопов, работает — снова переводчик). Подключенное к обоим компьютерами сигналирование позволяет начать подключение уже по WebRTC.

Offer и answer

WebRTC подключения используют «offer» и «answer»:

ICE-кандидаты

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

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

Благодаря технологии Trickle ICE (поддерживается не всеми браузерами — примечание переводчика) подключение между двумя WebRTC-устройствами может установиться в любой момент – как только будет найден подходящий «кандидат».

Разработчик должен подписаться на событие onicecandidate (все строчные!) и передавать другой стороне получаемые SDP-пакеты, где их нужно передаваться WebRTC с помощью метода addIceCandidate (а вот здесь, сюрприз, заглавная буква). Работает в обе стороны.

Подключение

Для установки подключения WebRTC использует такие штуки как STUN (Session Traversal Utilities for NAT) и TURN (Traversal Using Relay around NAT). Звучит страшно, но на самом деле всего лишь два сетевых протокола.

STUN-сервер

Первый из двух протоколов чуть сложнее эхо-сервера. Когда участники подключения хотят описать как к ним подключаться, им нужен их публичный IP-адрес. И скорее всего это не будет IP-адрес компьютера, пользовательским устройствам редко выделяют публичные адреса. Целую технологию NAT придумали, чтобы не выделять. Чтобы все-таки узнать свой публичный адрес, браузер делает запрос к STUN серверу. Проходя через NAT, сетевой пакет меняет свой обратный адрес на публичный. Получив пакет с запросом, STUN-сервер копирует обратный адрес пакета в его payload и отправляет пакет обратно. Проходя через NAT в обратную сторону, пакет теряет публичный IP-адрес, но копия этого адреса остается в payload, где ее может прочитать WebRTC.

Читайте также:  Что такое национальное богатство

TURN-сервер

TURN-сервер использует расширение STUN-протокола. Те же пакеты, заголовки, плюс новая штука: command. Сервер является прокси: оба клиента подключаются к нему через UDP-порт allocation и передают через сервер свои данные.

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

Отладка

Итак, вы дочитали до этого параграфа. Мы с переводчиком рады и помним, что статья об отладке WebRTC. Но все написанное выше — необходимый минимум, без которого можно даже не начинать. А вот если начать, и вы не располагаете нечеловеческим везением, то оно будет ломаться.

Оно будет ломаться множеством разных способов. Первый из них: отсутствие подключения. Вы передали обоим WebRTC настройки STUN и TURN-серверов, помогли им обменяться offer, answer и ICE кандидатами, а видео или голоса нет. С чего начать? С локального воспроизведения проблемы.

Локальная отладка WebRTC

Как я уже писал выше, основная работа WebRTC происходит на стороне браузера. STUN и TURN-серверы невероятно просты, так что большинство проблем случаются в вашем JavaScript-коде, который выполняется в двух браузерах. Sad but true. С другой стороны, если самое интересное происходит локально в браузерах, то у вас есть широкие возможности по отладке!

Первое что надо проверить — это ваше сигналирование. Именно ваш код передает между браузерами конфигурацию аудио с видео (offer, answer) и информацию о сетевых настройках (ice кандидаты). Вам нужно проверить, какие пакеты были отправлены, какие получены и переданы WebRTC:

Session Description Protocol

Пакеты Offer, Answer и ICE-кандидатов создаются WebRTC в текстовом формате SDP. На первый взгляд содержимое пакетов выглядит страшновато, но с небольшой подготовкой можно извлечь из них много пользы во время отладки. Wikipedia неплохо описывает SDP, но для вас я нашел описание получше.

Самое важное поле в SDP пакетах ICE кандидатов это typ. Для WebRTC поле может иметь одно из трех значений:

typ host

Тип host задает ICE-кандидат на подключение по локальной сети (WebRTC перебирает несколько кандидатов в надежде установить подключение, заранее неизвестно, какой получится — примечание переводчика). Такое подключение не требует ни STUN, ни TURN-сервера, так как в локальной сети устройства часто могут устанавливать сетевые подключения напрямую. При отладке с локальной сети вам достаточно проверить и отладить передачу host-пакетов и убедиться, что устройства могут отсылать друг другу UDP-пакеты. Хотя бывают исключения, на практике я видел конфигурации сети, при которых браузеру требовался TURN-сервер, чтобы подключиться… к себе.

typ srflx

Комбинация букв «srflx» расшифровывается как «Server Reflexive» и маркирует кандидатов на подключение с использованием внешнего IP-адреса, где для подключения достаточно STUN-сервера (при этом используется технология NAT penetration, которая успешна примерно в 80% случаев — примечание переводчика).

typ relay

«Relay» маркирует подключение через TURN-сервер, которое почти всегда успешно. Важно помнить, что WebRTC не обязано создать ровно три разных пакета с полем «typ»; как именно выбираются кандидаты – зависит от имплементации WebRTC в конкретной версии браузера.

Тестирование подключения к устройству

Google предлагает специальное веб-приложение для тестирования WebRTC-подключений на вашем устройстве. Откройте страницу, нажмите кнопку «start» и JavaScript код попробует установить подключение к серверу Google, используя сигналирование, STUN и TURN-серверы Google.

WebRTC Internals

Вы осмотрели все пакеты, проверили код, все выглядит правильно, но не работает? Для таких случаев Google снабдила свой браузер Chrome специальным разделом, который показывает внутренности WebRTC во время установки подключения и немного красивых графиков в случае успешного подключения. Чтобы воспользоваться, откройте в браузере специальную техническую ссылку:

Если у вас уже открыто приложение, использующее WebRTC, то вы сразу увидите кучу технических данных. В противном случае просто откройте еще одну вкладку и в ней что-нибудь, что использует WebRTC. Вкладка отображает все вызовы к объекту RTCPeerConnection и позволяет увидеть в реальном времени как устанавливается подключением.

Настройка ICE

Сверху страницы отображается ICE-строка, которая была использована при инициализации подключения. Если при ее формировании была допущена ошибка, это сразу же будет видно (под «ICE-строкой» автор имеет в виду конфигурацию объекта RTCPeerConnection со списком STUN и TURN-серверов (объект ‘iceServers’) – примечание переводчика). Возможно, там нет списка серверов? Вы должны сконфигурировать объект RTCPeerConnection до того, как сделали первый вызов createOffer или createAnswer.

События RTCPeerConnection

Следующий раздел internals показывает вызовы методов RTCPeerConnection и полученные от объекта события в хронологическом порядке. Ошибки заботливо подсвечиваются красным. Обратите внимание, что подсвеченное красным addIceCandidateFailed часто не является признаком ошибки и подключение может нормально установиться. В случае успешного подключения последним в списке будет событие iceconnectionstatechange с значением complete.

Раздел ‘stats’

Следующий раздел актуален, когда подключение успешно установлено. Он содержит статистику передаваемых данных и сетевые задержки. Два наиболее интересных параметра: ssrc и bweforvideo.

Функция getStats

Часто вы не сможете получить доступ к странице internals. Например, когда проблема случается у вашего пользователя. В таком случае вы можете получить те же данные, что показывает страница internals, вызывая метод getStats у объекта RTCPeerConnection. Этот метод устанавливает функцию обратного вызова, которая будет вызываться WebRTC каждый раз, когда происходит что-нибудь интересное. Вызываемая функция получает объект с теми полями, которые отображает страница internals:

Еще один полезный инструмент – это событие oniceconnectionstatechange объекта RTCPeerConnection. Обработчик события будет получать информацию о прогрессе подключения. Возможные варианты:

Черный прямоугольник вместо видео

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

Как потыкать палочкой снаружи

Кроме самого объекта RTCPeerConnection и отображаемых браузером internals вы можете использовать инструменты анализа сетевых пакетов, такие как Wireshark. Эти инструменты умеют отображать пакеты используемых WebRTC-протоколов. Например, Wireshark покажет вам содержимое STUN-пакетов в главном окне, и их можно отфильтровать, набрав в поле фильтра ключевое слово «stun»:

На что смотреть в ответах серверов? Если вы видите только ответы с типом Binding, это значит поддержку только STUN (рассказ о внешнем IP), и WebRTC сможет предложить только srflx-кандидатов. Если же в ответах есть специфичные для TURN пакеты Allocation и CreatePermission, то у WebRTC будет возможность попробовать подключиться через прокси-сервер. Анализатор пакетов помечает успешные и неуспешные Allocation. Если нет ни одного успешного, то скорее всего переданы неверные параметры доступа к TURN-серверам (которые почти всегда защищают логином и паролем — примечание переводчика).

Если в логе есть пакет CreatePermission Success Response, то можно предположить, что с конфигурацией STUN и TURN все хорошо. А если еще и ChannelBind пакет присутствует, то значит удалось установить подключение к TURN-серверу на высокой скорости.

Проблемы сотовой связи

В моей практике множество WebRTC-решений, устанавливающих подключение по WiFi, не могут подключиться по 3G/4G. Запущенное на мобильном устройстве приложение тяжелее отлаживать: у нас нет такого простого анализатора пакетов как Wireshark, а Safari не умеет показывать WebRTC internals. Логика подсказывает, что если приложение нормально работает по WiFi, то проблема не в самом приложении, а в сотовой связи. Как отладить? Взять ноутбук и подключить к нему 3G донгл. Так у вас появляются анализатор пакетов и удобные логи, с помощью которых можно за разумное время найти корень всех бед.

Источник

Информ портал о технике и не только