Webrtc клиент для windows

Как создать простое WebRTC-приложение

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

Содержание

Основная задача любого WebRTC-приложения – это установка RTCPeerConnection. Для его создания, необходимо понимать внутреннюю работу браузера, как он создает peer-to-peer соединение.

Для хорошего качества, требуется соединение, обеспечивающее передачу видео-звуковых фреймов со скоростью 40-60 в секунду. При такой скорости потеря нескольких фреймов не особо критична. Это значит, что получить свежие фреймы намного важнее, чем обеспечить доставку абсолютно всех и в нужное время. Наш мозг заполнит недостающие провалы (будем надеятсья). Это основная причина – почему технология WebRTC, в основном, использует протокол UDP вместо TCP. UDP (User Datagram Protocol) это тот протокол, который не гарантирует доставку каждого пакета.

WebRTC API

Рассмотрим функции и объекты WebRTC API, обеспечивающие создание и работу peer-соединения:

  • RTCPeerConnection – объект коннекта;
  • сигнальные функции взаимодействия между браузерами;
  • объект, описывающий сессию – Session Description Protocol (SDP) ;
  • ICE-кандидат – объект, описывающий возможности соединения конкретного браузера, их формируется много и выбирается наиболее подходящий.

Объект RTCPeerConnection

Это основная точка входа в WebRTC API, которая позволяет установить и инициализировать процесс соединения. Большинство действий мы будем совершать именно с ним. После его создания, к нему подсоединяется информацию о медиа-потоках. Главная задача этого объекта – начальная настройка соединения, поддержка сессии и контроль её состояние в браузере. Все эти функции инкапсулированы внутри объекта. Все они имеют событийную природу, по мере изменения состояния соединения, срабатывают соответствующие функции обратного вызова. Эти события дадут возможность изменять конфигурацию соединения и реагировать на события системы.

Объект RTCPeerConnection – это простой объект JS, который может быть создан оператором new.

В качестве аргумента он принимает конфигурационный объект. После создания мы вешаем колбек на событие, при котором удаленный пользователь подсоединяет медиа-поток к объекту RTCPeerConnection.

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

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

Все эти функции по коммуникации берет на себя сигнальный сервер, а сам процесс коммуникации состоит из следующих шагов:

Создание локального медиа потока.

  1. Генерация списка ICE-кандидатов для соединения.
  2. Выбор необходимого пользователя для контакта;
  3. Отсылка сигнала-приглашения удаленному пользователю о том, что кто-то хочет с ним соединиться;
  4. Пользователь соглашается или отвергает приглашение;
  5. Если приглашение принято, то первый пользователь инициализирует RTCPeerConnection-соединение с удаленным пользователем и генерирует свои ICE кандидаты;
  6. Оба пользователя начинают обмен ICE-кандидатами с информацией о конфигурации их устройств, программного окружения и местоположения в сети;
  7. Установка либо провал соединения.

Однако, спецификация WebRTC не содержит никаких стандартов относительно того, каким образом эта информация будет передаваться между пользователями и на каких технологиях должен быть построен сигнальный сервер. На сегодняшний день существует множество решений на Java, Python, NodeJS, PHP, позволяющих создать сигнальный сервер на ряду с такими технологиями из телефонии как XMPP и SIP.

Session Description Protocol (SDP)

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

SDP – это текстовые данные, предоставляемые браузером в формате ключ-значение и разделенные переносом строк,.

Если вывести в консоль эту строку, то она может выглядеть так:

Как видим, это не простой объект. Он содержит много разной информации. Абсолютно не обязательно понимать суть каждого параметра т.к. вам не нужно будет работать с этим объектом напрямую.

Поиск оптимального маршрута между пользователями

Существует 2 способа установки соединения STUN и TURN. Схематически их можно отобразить следующим образом:

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

В данном случае это соединение будет использовать систему NAT и в качестве STUN-сервера можно использовать как свой собственный, так и поставляемые производителями браузера публичные сервера.

NAT (Network Address Translation) – это механизм автоматического преобразования роутером адресов источника в отсылаемых пакетах, и адресов приемника в принимаемых на реальный внутренний адрес сети.

В некоторых случаях, политика в подсетях запрещает работу по STUN-протоколу. В этом случае, происходит попытка использовать TURN-сервер как коммутатор, в котором эмулируется удаленное peer соединение для обоих клиентов. Это называется – в обход NAT. При этом клиент получает данные от TURN сервера – как будто это удаленный браузер. Из за того, что использование TURN включает в себя дополнительные расходы, данный способ считается менее привлекательным и используется «на крайний случай». Однако, это вопрос спорный и использование TURN-шлюза зачастую может быть оправдано.

Интерактивная установка соединения

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

Читайте также:  Как сделать нумерацию страниц windows word

Построение базового WebRTC-приложения

Попробуем создать соединение между двумя пользователя внутри одной страницы. Приложение будет выполнять последовательность действий:

  • создание 2-х RTCPeerConnection объектов;
  • создание SDP offer и передача его между ними;
  • поиск ICE кандидата для соединения;
  • установка WebRTC-соединения.

Определим шаблон html страницы с двумя элементами video и кнопками для создания видеопотока, вызова удаленного абонента и завершения соединения.

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

Теперь определим переменные для локального медиапотока, объектов RTCPeerConnection, и параметров offer запроса.

Последние две функции вспомогательные, по переданному соединению они возвращают противоположное соединение и его название.

Наполним функцию start, забрав видеопоток с локальной камеры и добавив его к элементу localVideo.


После нажатия Start мы должны увидеть себя в маленьком контейнере video.

Опишем функцию call и то, что она использует:

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

addTrack(track,stream) добавляет новые медиадорожки в коллекцию stream, которые должны быть переданы клиенту на удаленный peer. Дело в том, что по сети передаются не потоки stream, а медиадорожки. Вы вправе добавить несколько дорожек из разных stream-объектов (в случае если у вас много камер и микрофонов). Функция addTrack служит для их группировки и последующей синхронизации. В нашем случае мы оперируем одним объектом stream и и группируем в нем его же дорожки. Получить текущие дорожки можно из объекта stream stream.getTracks() . Этот метод вызывает событие negotiationneeded, но мы это не используем.

createOffer([options]) формирует объект SDP offer для инициализации нового WebRTC-соединения. Этот объект содержит:

  • информацию о всех медиадорожках, подключенных в сессию WebRTC;
  • кодеки;
  • опции браузера;
  • ICE кандидаты.

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

createAnswer([options]) похож на предыдущий метод createOffer, но вызывается в ответ на пришедший SDP offer от удаленного хоста.

setLocalDescription(SDP) и setRemoteDescription(SDP) – эти два метода устанавливают или обновляют информацию о локальной или удаленной конфигурации медиапотоков. Обычно эти методы вызываются сразу после createOffer() и передачи SDP offer-а через сигнальный сервер c целью обновить информацию.

В нашем примере мы пока не используем сигнальный сервер.

addIceCandidate() . Когда наше приложение получает ICE кандидата из удаленного хоста его необходимо передать ICE агенту внутри объекта RTCPeerConnection. За это отвечает функция addIceCandidate() . Если приходит пустая строка, это означает, что все кандидаты были доставлены. Обычно таких кандидатов много и каждый из них описывает свой собственный потенциальный способ соединения.

В нашем примере, после создания объектов:

Мы подвязываем функцию onIceCandidate к событию icecandidate. Это событие будет инициировано после вызова метода setLocalDescription или setRemoteDescription.

В функции onIceCandidate мы добавляем переданный ICE кандидат в противоположное соединение, которое получаем ф-цией getOtherPc() см. выше .

Далее, вызываем ф-цию onCreateOfferSuccess() первого соединения.

В этой функции мы совершаем 3 действия:

  1. Устанавливаем setLocalDescription из поступившего SDP offer для pc1.
  2. Устанавливаем setRemoteDescription из поступившего SDP offer для pc2.
  3. Формируем SDP offer из соединения pc2.

Третий пункт вызывается в последнюю очередь и устанавливает SDP offer функциями pc2.setLocalDescription и pc1.setRemoteDescription SDP уже в обратном направлении.

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

В конце привожу код сервисных функций, используемых для отладки.

Результат работы приложения:

На этом все. В следующей статье мы поговорим о том, как написать сигнальный сервис Tornado. Чтобы первыми узнать о новой публикации и получать больше полезного контента, подпишитесь на наш блог.

Если вас заинтересовали возможности, которые предоставляет WebRTC-приложение – оставьте заявку на сайте. Специалисты Wezom создадут действительно эффективное решение для вашего бизнеса.

Оставьте ваши контактные данные. Наш менеджер свяжется и проконсультирует вас.

Наш менеджер свяжется с Вами в ближайшее время

Юзаем WebRTC + сокеты для звонков из чистого браузера

Содержание статьи

Технологиям для звонков из браузера уже много лет: Java, ActiveX, Adobe Flash. В последние несколько лет стало ясно, что плагины и левые виртуальные машины не блещут удобством (зачем мне вообще что-то устанавливать?) и, самое главное, безопасностью. Что же делать? Выход есть!

До последнего времени в IP-сетях использовалось несколько протоколов для IP-телефонии или видео: SIP, наиболее распространенный протокол, сходящие со сцены H.323 и MGCP, Jabber/Jingle (используемый в Gtalk), полуоткрытые Adobe RTMP* и, конечно, закрытый Skype. Проект WebRTC, инициированный Google, пытается перевернуть положение дел в мире IP- и веб-телефонии, сделав ненужными все программные телефоны, включая Skype. WebRTC не просто реализует все коммуникационные возможности непосредственно внутри браузера, установленного сейчас практически на каждом устройстве, но пытается одновременно решить более общую задачу коммуникаций между пользователями браузеров (обмен различными данными, трансляция экранов, совместная работа с документами и многое другое).

WebRTC со стороны веб-разработчика

С точки зрения веб-разработчика WebRTC состоит из двух основных частей:

  • управление медиапотоками от локальных ресурсов (камеры, микрофона или экрана локального компьютера) реализуется методом navigator.getUserMedia, возвращающим объект MediaStream;
  • peer-to-peer коммуникации между устройствами, генерирующими медиапотоки, включая определение способов связи и непосредственно их передачу — объекты RTCPeerConnection (для отправки и получения аудио- и видеопотоков) и RTCDataChannel (для отправки и получения данных из браузера).

Что будем делать?

Мы разберемся, как организовать простейший многопользовательский видеочат между браузерами на основе WebRTC с использованием веб-сокетов. Экспериментировать начнем в Chrome/Chromium, как наиболее продвинутых в плане WebRTC браузерах, хотя вышедший 24 июня Firefox 22 почти их догнал. Нужно сказать, что стандарт еще не принят, и от версии к версии API может меняться. Все примеры проверялись в Chromium 28. Для простоты не будем следить за чистотой кода и кросс-браузерностью.

MediaStream

Первый и самый простой компонент WebRTC — MediaStream. Он предоставляет браузеру доступ к медиапотокам с камеры и микрофона локального компьютера. В Chrome для этого необходимо вызвать функцию navigator.webkitGetUserMedia() (так как стандарт еще не завершен, все функции идут с префиксом, и в Firefox эта же функция называется navigator.mozGetUserMedia()). При ее вызове пользователю будет выведен запрос о разрешении доступа к камере и микрофону. Продолжить звонок можно будет только после того, как пользователь даст свое согласие. В качестве параметров этой функции передаются параметры требуемого медиапотока и две callback-функции: первая будет вызвана в случае успешного получения доступа к камере/микрофону, вторая — в случае ошибки. Для начала создадим HTML-файл rtctest1.html с кнопкой и элементом :

Читайте также:  Список клиентов dhcp windows

Microsoft CU-RTC-Web

Microsoft не была бы Microsoft, если бы в ответ на инициативу Google не выпустила немедленно свой собственный несовместимый нестандартный вариант под названием CU-RTC-Web (html5labs.interoperabilitybridges.com/cu-rtc-web/cu-rtc-web.htm). Хотя доля IE, и так небольшая, продолжает сокращаться, количество пользователей Skype дает Microsoft надежду потеснить Google, и можно предположить, что именно этот стандарт будет использоваться в браузерной версии Skype. Стандарт Google ориентирован в первую очередь на коммуникации между браузерами; в то же время основная часть голосового трафика по-прежнему остается в обычной телефонной сети, и шлюзы между ней и IP-сетями необходимы не только для удобства использования или более быстрого распространения, но и в качестве средства монетизации, которое позволит большему числу игроков их развивать. Появление еще одного стандарта может не только привести к неприятной необходимости разработчикам поддерживать сразу две несовместимых технологии, но и в перспективе дать пользователю более широкий выбор возможного функционала и доступных технических решений. Поживем — увидим.

Включение локального потока

Внутри тегов нашего HTML-файла объявим глобальную переменную для медиапотока:

Первым параметром методу getUserMedia необходимо указать параметры запрашиваемого медиапотока — например просто включить аудио или видео:

Либо указать дополнительные параметры:

Вторым параметром методу getUserMedia необходимо передать callback-функцию, которая будет вызвана в случае его успешного выполнения:

Третий параметр — callback-функция обработчик ошибки, который будет вызван в случае ошибки

Собственно вызов метода getUserMedia — запрос доступа к микрофону и камере при нажатии на первую кнопку

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

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

Запрос на доступ к камере и микрофону

Хакер #176. Анонимность в интернете

Выбрать устройства, к которым получит доступ Chrome, можно в Settings («Настройки»), линк Show advanced settings («Показать дополнительные настройки»), раздел Privacy («Личные данные»), кнопка Content («Настройки контента»). В браузерах Firefox и Opera выбор устройств осуществляется из выпадающего списка непосредственно при разрешении доступа.

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

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

RTCMediaConnection

RTCMediaConnection — объект, предназначенный для установления и передачи медиапотоков по сети между участниками. Кроме того, этот объект отвечает за формирование описания медиасессии (SDP), получение информации об ICE-кандидатах для прохождения через NAT или сетевые экраны (локальные и с помощью STUN) и взаимодействие с TURN-сервером. У каждого участника должно быть по одному RTCMediaConnection на каждое соединение. Медиапотоки передаются по шифрованному протоколу SRTP.

TURN-серверы

ICE-кандидаты бывают трех типов: host, srflx и relay. Host содержат информацию, полученную локально, srflx — то, как узел выглядит для внешнего сервера (STUN), и relay — информация для проксирования трафика через TURN-сервер. Если наш узел находится за NAT’ом, то host-кандидаты будут содержать локальные адреса и будут бесполезны, кандидаты srflx помогут только при определенных видах NAT и relay будут последней надеждой пропустить трафик через промежуточный сервер.

Пример ICE-кандидата типа host, с адресом 192.168.1.37 и портом udp/34022:

Общий формат для задания STUN/TURN-серверов:

Публичных STUN-серверов в интернете много. Большой список, например, есть здесь. К сожалению, решают они слишком малую часть проблем. Публичных же TURN-серверов, в отличие от STUN, практически нет. Связано это с тем, что TURN-сервер пропускает через себя медиапотоки, которые могут значительно загружать и сетевой канал, и сам сервер. Поэтому самый простой способ подключиться к TURN-серверам — установить его самому (понятно, что потребуется публичный IP). Из всех серверов, на мой взгляд, наилучший rfc5766-turn-server. Под него есть даже готовый образ для Amazon EC2.

С TURN пока не все так хорошо, как хотелось бы, но идет активная разработка, и хочется надеяться, через какое-то время WebRTC если не сравняется со Skype по качеству прохождения через трансляцию адресов (NAT) и сетевые экраны, то по крайней мере заметно приблизится.

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

Взаимодействие RTCPeerConnection

Выбор способа передачи возлагается на разработчика — хоть вручную. Как только обмен необходимыми данными пройдет, RTCMediaConnection установит медиапотоки автоматически (если получится, конечно).

Модель offer-answer

Для установления и изменения медиапотоков используется модель offer/answer (предложение/ответ; описана в RFC3264) и протокол SDP (Session Description Protocol). Они же используются и протоколом SIP. В этой модели выделяется два агента: Offerer — тот, кто генерирует SDP-описание сессии для создания новой или модификации существующей (Offer SDP), и Answerer — тот, кто получает SDP-описание сессии от другого агента и отвечает ему собственным описанием сессии (Answer SDP). При этом в спецификации требуется наличие протокола более высокого уровня (например, SIP или собственного поверх веб-сокетов, как в нашем случае), отвечающего за передачу SDP между агентами.

Какие данные необходимо передать между двумя RTCMediaConnection, чтобы они смогли успешно установить медиапотоки:

  • Первый участник, инициирующий соединение, формирует Offer, в котором передает структуру данных SDP (этот же протокол для той же цели используется в SIP), описывающую возможные характеристики медиапотока, который он собирается начать передавать. Этот блок данных необходимо передать второму участнику. Второй участник формирует Answer, со своим SDP и пересылает его первому.
  • И первый и второй участники выполняют процедуру определения возможных ICE-кандидатов, с помощью которых к ним сможет передать медиапоток второй участник. По мере определения кандидатов информация о них должна передаваться другому участнику.

Последовательность обмена RTCPeerConnection

Формирование Offer

Для формирования Offer нам понадобятся две функции. Первая будет вызываться в случае его успешного формирования. Второй параметр метода createOffer() — callback-функция, вызываемая в случае ошибки при его выполнении (при условии, что локальный поток уже доступен).

Дополнительно понадобятся два обработчика событий: onicecandidate при определении нового ICE-кандидата и onaddstream при подключении медиапотока от дальней стороны. Вернемся к нашему файлу. Добавим в HTML после строк с элементами еще одну:

И после строки с элементом (на будущее):

Также в начале JavaScript-кода объявим глобальную переменную для RTCPeerConnection:

Читайте также:  Linux zip без сжатия

При вызове конструктора RTCPeerConnection необходимо указать STUN/TURN-серверы. Подробнее о них см. врезку; пока все участники находятся в одной сети, они не требуются.

Параметры для подготовки Offer SDP

Первый параметр метода createOffer() — callback-функция, вызываемая при успешном формировании Offer

Второй параметр — callback-функция, которая будет вызвана в случае ошибки

И объявим callback-функцию, которой будут передаваться ICE-кандидаты по мере их определения:

А также callback-функцию для добавления медиапотока от дальней стороны (на будущее, так как пока у нас только один RTCPeerConnection):

При нажатии на кнопку «createOffer» создадим RTCPeerConnection, зададим методы onicecandidate и onaddstream и запросим формирование Offer SDP, вызвав метод createOffer():

Сохраним файл как rtctest2.html, выложим его на сервер, откроем в браузере и посмотрим в консоли, какие данные формируются во время его работы. Второе видео пока не появится, так как участник всего один. Напомним, SDP — описание параметров медиасессии, доступные кодеки, медиапотоки, а ICE-кандидаты — возможные варианты подключения к данному участнику.

Формирование Answer SDP и обмен ICE-кандидатами

И Offer SDP, и каждого из ICE-кандидатов необходимо передать другой стороне и там после их получения у RTCPeerConnection вызвать методы setRemoteDescription для Offer SDP и addIceCandidate для каждого ICE-кандидата, полученного от дальней стороны; аналогично в обратную сторону для Answer SDP и удаленных ICE-кандидатов. Сам Answer SDP формируется аналогично Offer; разница в том, что вызывается не метод createOffer, а метод createAnswer и перед этим RTCPeerConnection методом setRemoteDescription передается Offer SDP, полученный от вызывающей стороны.

Добавим еще один видеоэлемент в HTML:

И глобальную переменную для второго RTCPeerConnection под объявлением первой:

Обработка Offer и Answer SDP

Формирование Answer SDP очень похоже на Offer. В callback-функции, вызываемой при успешном формировании Answer, аналогично Offer, отдадим локальное описание и передадим полученный Answer SDP первому участнику:

Callback-функция, вызываемая в случае ошибки при формировании Answer, полностью аналогична Offer:

Параметры для формирования Answer SDP:

При получении Offer вторым участником создадим RTCPeerConnection и сформируем Answer аналогично Offer:

Для того чтобы в рамках нашего примера передать Offer SDP от первого участника ко второму, раскомментируем в функции pc1createOffersuccess() строку вызова:

Чтобы реализовать обработку ICE-кандидатов, раскомментируем в обработчике события готовности ICE-кандидатов первого участника pc1_onicecandidate() его передачу второму:

Обработчик события готовности ICE-кандидатов второго участника зеркально подобен первому:

Сallback-функцию для добавления медиапотока от первого участника:

Завершение соединения

Добавим еще одну кнопку в HTML

И функцию для завершения соединения

Сохраним как rtctest3.html, выложим на сервер и откроем в браузере. В этом примере реализована двусторонняя передача медиапотоков между двумя RTCPeerConnection в рамках одной закладки браузера. Чтобы организовать через сеть обмен Offer и Answer SDP, ICE-кандидатами между участниками и другой информацией, потребуется вместо прямого вызова процедур реализовать обмен между участниками с помощью какого-либо транспорта, в нашем случае — веб-сокетов.

Трансляция экрана

Функцией getUserMedia можно также захватить экран и транслировать как MediaStream, указав следующие параметры:

Для успешного доступа к экрану должно выполняться несколько условий:

  • включить флаг снимка экрана в getUserMedia() в chrome://flags/,chrome://flags/;
  • исходный файл должен быть загружен по HTTPS (SSL origin);
  • аудиопоток не должен запрашиваться;
  • не должно выполняться несколько запросов в одной закладке браузера.

Библиотеки для WebRTC

Хотя WebRTC еще и не закончен, уже появилось несколько базирующихся на нем библиотек. JsSIP предназначена для создания браузерных софтфонов, работающих с SIP-коммутаторами, такими как Asterisk и Camalio. PeerJS упростит создание P2P-сетей для обмена данными, а Holla сократит объем разработки, необходимый для P2P-связи из браузеров.

Node.js и socket.io

Для того чтобы организовать обмен SDP и ICE-кандидатами между двумя RTCPeerConnection через сеть, используем Node.js с модулем socket.io.

Установка последней стабильной версии Node.js (для Debian/Ubuntu) описана здесь

Установка под другие операционные системы описана здесь

С помощью npm (Node Package Manager) установим socket.io и дополнительный модуль express:

Проверим, создав файл nodetest2.js для серверной части:

И nodetest2.html для клиентской части:

и откроем страницу http://localhost:80 (если запущен локально на 80-м порту) в браузере. Если все успешно, в консоли JavaScript браузера мы увидим обмен событиями между браузером и сервером при подключении.

Обмен информацией между RTCPeerConnection через веб-сокеты

Клиентская часть

Сохраним наш основной пример (rtcdemo3.html) под новым именем rtcdemo4.html. Подключим в элементе библиотеку socket.io:

И в начале сценария JavaScript — подключение к веб-сокетам:

Заменим прямой вызов функций другого участника отправкой ему сообщения через веб-сокеты:

В функции hangup() вместо прямого вызова функций второго участника передадим сообщение через веб-сокеты:

И добавим обработчики получения сообщения:

Серверная часть

На серверной стороне сохраним файл nodetest2 под новым именем rtctest4.js и внутри функции io.sockets.on(‘connection’, function (socket) < . >добавим прием и отправку сообщений клиентов:

Кроме этого, изменим имя HTML-файла:

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

Заключение

Получившийся пример очень условен, но если немного универсализировать обработчики событий, чтобы они не различались у вызывающей и вызываемой стороны, вместо двух объектов pc1 и pc2 сделать массив RTCPeerConnection и реализовать динамическое создание и удаление элементов ,то получится вполне пригодный для использования видеочат. В этом уже нет особой специфики, связанной с WebRTC, и пример простейшего видеочата на несколько участников (как и тексты всех примеров статьи) есть на диске, идущем с журналом. Впрочем, и в интернете можно найти уже немало хороших примеров. В частности, при подготовке статьи использовались: simpl.info getUserMedia, simpl.info RTCPeerConnection,WebRTC Reference App.

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

Оцените статью