![Рис 1. Одновременная работа в редакторе схем Рис 1. Одновременная работа в редакторе схем](https://habrastorage.org/getpro/habr/upload_files/927/3d9/182/9273d918299a97c1cd634f9d7920c67a.gif)
WebRTC позволяет браузерам обмениваться информацией напрямую без сервера. Можно передавать видео, звук и данные. Установить WebRTC соединение можно разными способами. В статье описано как WebRTC соединение устанавливается между пользователями редактора схем dgrm.net.
В DGRM клиенты не соединяются “каждый с каждым”. События клиентам рассылает браузер инициатора встречи
Когда пользователь добавляет фигуру, меняет цвет или двигает курсор - данные о событии по WebRTC отправляются браузеру инициатора встречи. Инициатор пересылает данные другим пользователям.
![Рис 2. Клиенты не соединены “каждый с каждым”. Клиенты отправляют события инициатору встречи. Инициатор пересылает события другим клиентам. Рис 2. Клиенты не соединены “каждый с каждым”. Клиенты отправляют события инициатору встречи. Инициатор пересылает события другим клиентам.](https://habrastorage.org/getpro/habr/upload_files/f76/735/ad3/f76735ad36bf36af1d753912dcd265a9.png)
Для соединения по WebRTC браузеры должны обменяться параметрами соединения
Когда клиент подключается к инициатору, он должен сообщить инициатору параметры соединения: требования к соединению и свои сетевые адреса.
Пример требований к соединению: должно ли соединение поддерживать видео, какой кодек использовать и т.п. DGRM передает только JSON-строки.
Сетевых адресов у клиента может быть несколько. Например, один адрес в локальной сети, другой - во внешней. Если клиент и инициатор встречи в одной локальной сети - для соединения будет использоваться адрес в локальной сети. Адрес во внешней сети браузер сам узнать не может. Для получения своего внешнего адреса браузер делает запрос к специальному STUN серверу. STUN сервер возвращает браузеру его внешние адреса. Есть бесплатные STUN сервера, например у Google. Хорошая статья о том, как устроена адресация в WebRTC: Просто о WebRTC (forasoft.github.io).
Параметры соединения, которые клиент передает при подключении, называются SDPOffer. Инициатор встречи на основе SDPOffer формирует и отправляет клиенту SDPAnswer. SDPAnswer содержит сетевые адреса инициатора.
![Рис 3. Для соединения по WebRTC клиент должен передать инициатору встречи параметры соединения SDPOffer. На основе SDPOffer инициатор формирует SDPAnswer и передает его клиенту. После этого браузеры узнают адреса друг друга и устанавливается WebRTC соединение. Рис 3. Для соединения по WebRTC клиент должен передать инициатору встречи параметры соединения SDPOffer. На основе SDPOffer инициатор формирует SDPAnswer и передает его клиенту. После этого браузеры узнают адреса друг друга и устанавливается WebRTC соединение.](https://habrastorage.org/getpro/habr/upload_files/a8f/bed/da2/a8fbedda2ed623edf093de6d62735ac6.png)
Обмен параметрами WebRTC соединения через свой сервер
Обменяться параметрами соединения можно разными способами. Например вручную через мессенджер. SDPOffer и SDPOffer - это строки. С помощью JavaScript и API браузера можно получить SDPOffer/SDPAnswer, вывести на страницу, скопировать и отправить в мессенджер.
v=0
o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com
s=
c=IN IP4 host.atlanta.example.com
t=0 0
m=audio 49170 RTP/AVP 0 8 97
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 iLBC/8000
m=video 51372 RTP/AVP 31 32
a=rtpmap:31 H261/90000
a=rtpmap:32 MPV/90000
Листинг 1. Пример SDPOffer. SDPOffer и SDPAnswer это строки
В DGRM для обмена параметрами соединения используется свой сервер.
![Рис 4. Создание онлайн встречи в dgrm.net Рис 4. Создание онлайн встречи в dgrm.net](https://habrastorage.org/getpro/habr/upload_files/814/7b6/c20/8147b6c2003320eae03a780b672944dc.png)
Когда инициатор встречи нажимает “Live collaboration”:
Браузер инициатора отправляет на сервер DGRM запрос “создать встречу”. При этом передается случайный id встречи.
Сервер запоминает id встречи.
Инициатор отправляет ссылку с id встречи через мессенджер.
Клиент проходит по ссылке.
Браузер клиента генерирует SDPOffer. Отправляет id встречи, свой id клиента и SDPOffer на сервер.
Сервер запоминает SDPOffer.
Браузер инициатора периодически опрашивает сервер “дай SDPOffer-ы для id встречи”.
Браузер инициатора при получении SDPOffer генерирует SDPAnswer. Посылает id встречи, id клиента и SDPAnswer на сервер.
Сервер запоминает SDPAnswer
Браузер клиента после паузы запрашивает у сервера SDPAnswer.
Как только клиент получает SDPAnswer, устанавливается WebRTC соединение.
![Рис 5. Схема обмена параметрами WebRTC соединения через свой сервер Рис 5. Схема обмена параметрами WebRTC соединения через свой сервер](https://habrastorage.org/getpro/habr/upload_files/c7f/b78/93a/c7fb7893ab6414e727752d943d9ddc29.png)
Уточнения к схеме
Почему для обмена SDPOffer/SDPAnswer не используются web-сокеты?
Здесь используются периодические опросы сервера. WebRTC соединение устанавливается за пару секунд. Если использовать web-сокеты или server-events, то WebRTC соединение будет устанавливаться быстрее. Зато в такой схеме меньше требования к серверу.
Почему инициатор не может отправить клиенту SDPAnswer сразу по WebRTC?
Инициатор получил SDPOffer. SDPOffer содержит адреса клиента. Почему не отправить SDPAnswer сразу клиенту? Не знаю. У меня не получилось. Спрашивал в группах по WebRTC, говорят так нельзя.
Почему SDPOffer делает клиент, а не инициатор?
Инициатор может сделать один SDPOffer для всех клиентов. Тогда схема обмена упростится. Почему так не сделано? Инициатор должен иметь WebRTC соединение с каждым клиентом. Одни SDPOffer нельзя использовать в нескольких соединениях.
Я не хочу делать свою реализацию. Есть готовые решения?
Есть сервисы для разработчиков которые не только производят обмен SDPOffer/SDPAnswer, но и предлагают TURN сервер. Если соединение p2p не удается установить, данные начинают отправляться через TURN сервер. TURN - это запасной вариант.