- PVSM.RU - https://www.pvsm.ru -

Статей про WebRTC уже достаточно много и в интернетах, и на Хабре (здесь [1] и здесь [2]), повторять их ещё раз не имеет особого смысла, поэтому тут приведем наш личный опыт и впечатления, полученные при раработке live.pics.io [3].
Live.pics.io позволяет создавать приватные сессии для совместного просмотра и обсуждения изображений голосом. Это могут быть любые изображения: от фотографий, до макетов дизайна и презентаций. Pазрабатывая pics.io, мы достаточно хорошо научились работать с разными raw форматами в браузере, поэтому можно не заморачиваться с конвертацией и закидывать фотографии сразу после съемки (будут рады владельцы Canon’ов и Nikon’ов, остальные камеры пока требуют конвертации в DNG).
На самом деле, использовать WebRTC — это практически то же самое, что использовать сокеты. Но немного по-другому (совсем чуть-чуть). Нам нужно передавать изображение и звук. Берем RTCPeerConnection для соединения между пирами, MediaStream для трансляции аудио и RTCDataChannel для передачи изображений. Еще, для того, чтобы все это заработало, понадобится небольшой серверсайд для соединения пиров и передачи управляющих инструкций. Но об этом чуть позже.

Так уж случилось, что наш основной проект (pics.io) разрабатывается на Backbone [4]. Мы давно хотели попробовать распиареный [5] Exoskeleton [6], который, как бы, то же самое… Но не совсем. В нашем случае Exoskeleton не так уж необходим, но нам просто захотелось поиграться с новой штукой и выпустить ее в продакшн. Помоему мы не прогадали. Еще надо отдать должное автору @PaulMiller [7], который очень активно поддерживает свое детище. Вообще, мы не то чтобы ненавидим jQuery, от которого Exoskeleton спасает, но мы убедились, что под современные браузеры можно писать на чистом JS. Я искренне надеюсь, что Exoskeleton повторит путь Lodash [8] и завоюет сердца бекбонщиков.
Мы решили, что правильнее и быстрее для развёртывания WebRTC части будет использовать готовое и протестированное решение. После изучения нескольких open source проектов, которые оборачивают WebRTC сервисы, выбор пал на PeerJS: отчасти из-за большого количества звездочек на GitHub, а отчасти из-за совета @Lvivsky [9], который собаку съел на создании библиотеки speaker [10] на Dart/WebRTC.
PeerJS — это обертка над WebRTC, которая позволяет абстрагироваться от его внутренностей. В конце концов нам всё же пришлось поковыряться в его исходниках, когда мы наткнулись на ограничение передаваемых файлов по RTCDataChannel в ~6Mb. В целом, библиотека оставила только приятные впечатления, да и мейнтейнеры проекта оперативно нам помогали.
Первое впечатление от PeerJS было изумительным: одна строка на сервер сайде, отличный интерфейс на клиенте, поддержка Media call (audio/video) и DataConnections. И что самое приятное PeerJS помогает продолеть ограничение на объем передаваемых данных через DataConnections в Chrome 31, который пока не научился передавать больше 1100 байт. Но не все коту масленица, RTCDataChannel падает с абсолютно неинформативным ворнингом Uncaught SyntaxError: An invalid or illegal string was specified. После пары литров кофе и общения с контрибьюторами PeerJS выяснилось, что Chrome ограничивает скорость передачи данных до 60kb/s. Вдобавок оказалось что максимальный размер передаваемого файла получился ~6,3M. В приниципе, этого достаточно для того, чтобы передавать jpeg, извлеченный из raw-файла.

Накануне релиза мы не могли не облажаться. Соединение в локальной сети работало превосходно (как MediaStream, так и DataChannel), но когда кто-то подключался не из офиса, наш восторг пропадал, начинались необъяснимые проблемы, которые воспроизводились нестабильно. То звук, то данные до гостей не доходили.
Мы выделили несколько пунктов которые могли влиять на это:
Начали с того, что вместо DataChannel добавили Signaling сервер на WebSocket, c помощью которого связали существующие пиры, но это не решило проблему.
Поиски бага тоже не увенчались успехом. Их было найдена уйма, но и это не помогло.
“Все-таки NAT” — решили мы и, как оказались, правы. Странно, но решение этой проблемы не очень хорошо описано в документации. Изначально большинство библиотек использует по умолчанию сервера:
[{url:'stun:stun.l.google.com:19302'},
{url:'turn:homeo@turn.bistri.com:80', credential: 'homeo'}]
Но, к сожалению, нам не хватило этого и пришлось серфить в поисках дополнительных серверов. В итоге мы получили огромный конфиг для ICEServers
[{url:'stun:stun01.sipphone.com'},
{url:'stun:stun.ekiga.net'},
{url:'stun:stun.fwdnet.net'},
{url:'stun:stun.ideasip.com'},
{url:'stun:stun.iptel.org'},
{url:'stun:stun.rixtelecom.se'},
{url:'stun:stun.schlund.de'},
{url:'stun:stun.l.google.com:19302'},
{url:'stun:stun1.l.google.com:19302'},
{url:'stun:stun2.l.google.com:19302'},
{url:'stun:stun3.l.google.com:19302'},
{url:'stun:stun4.l.google.com:19302'},
{url:'stun:stunserver.org'},
{url:'stun:stun.softjoys.com'},
{url:'stun:stun.voiparound.com'},
{url:'stun:stun.voipbuster.com'},
{url:'stun:stun.voipstunt.com'},
{url:'stun:stun.voxgratia.org'},
{url:'stun:stun.xten.com'},
{
url: 'turn:numb.viagenie.ca',
credential: 'muazkh',
username: 'webrtc@live.com'
},
{
url: 'turn:192.158.29.39:3478?transport=udp',
credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
username: '28224511:1379330808'
},
{
url: 'turn:192.158.29.39:3478?transport=tcp',
credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
username: '28224511:1379330808'
}]
После этого мы благополучно пробили стены NAT и услышали голоса людей из других подсетей, городов и стран.
На данный момент у реализаций WebRTC есть проблема c работой между разными браузерами, но и Firefox и Chrome активно двигаются в этом направлении. Через пару-тройку версий web уже получит эту поддержку.
STUN и TURN — пожалуй основная проблема, о которой почему-то мало пишут. Постоянно тестируя, мы заметили, что внутри одной сети все друг-друга слышали и прекрасно получали данные, но люди, которые сидели за роутерами испытывали постоянные проблемы. На это мы потратили огромное количество нервов, так как не особо тесно работали с сетевыми протоколами и не до конца понимали, зачем это нужно.
Очень крутое времяпрепровождение, масса новых эмоций и навыков и чувство удовлетворения от того, что на выходе готовый продукт. Но вы рискуете быть выжатым весь следующий день.
www.html5rocks.com/en/tutorials/webrtc/basics/ [11]
www.youtube.com/watch?v=p2HzZkd2A40 [12]
www.youtube.com/watch?v=E8C8ouiXHHk [13]
www.webrtc-experiment.com/ [14]
www.webrtc.org/ [15]
speakerdeck.com/feross/webrtc-data-black-magic [16]
Автор: yetithefoot
Источник [17]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/49041
Ссылки в тексте:
[1] здесь: http://habrahabr.ru/post/198632/
[2] здесь: http://habrahabr.ru/post/187270/
[3] live.pics.io: http://live.pics.io
[4] Backbone: http://backbonejs.org/
[5] распиареный: http://habrahabr.ru/post/198800/
[6] Exoskeleton: http://exosjs.com/
[7] @PaulMiller: https://twitter.com/paulmillr
[8] Lodash: http://lodash.com/
[9] @Lvivsky: https://github.com/lvivski
[10] speaker: https://github.com/lvivski/speaker
[11] www.html5rocks.com/en/tutorials/webrtc/basics/: http://www.html5rocks.com/en/tutorials/webrtc/basics/
[12] www.youtube.com/watch?v=p2HzZkd2A40: http://www.youtube.com/watch?v=p2HzZkd2A40
[13] www.youtube.com/watch?v=E8C8ouiXHHk: http://www.youtube.com/watch?v=E8C8ouiXHHk
[14] www.webrtc-experiment.com/: https://www.webrtc-experiment.com/
[15] www.webrtc.org/: http://www.webrtc.org/
[16] speakerdeck.com/feross/webrtc-data-black-magic: https://speakerdeck.com/feross/webrtc-data-black-magic
[17] Источник: http://habrahabr.ru/post/203306/
Нажмите здесь для печати.