Опубликовано: 4 ноября 2013 г.
WebRTC обеспечивает связь между двумя узлами (peer-to-peer). Для этого требуются серверы, чтобы клиенты могли обмениваться метаданными и координировать связь посредством процесса, называемого сигнализацией . Серверы также помогают клиентам справляться с трансляторами сетевых адресов (NAT) и брандмауэрами.
Здесь вы узнаете, как создать службу сигнализации и справиться со сложностями реального взаимодействия с серверами STUN и TURN. Вы также поймете, как приложения WebRTC могут обрабатывать многосторонние звонки и взаимодействовать с такими сервисами, как VoIP и PSTN (также известные как телефоны).
Что такое сигнализация?
Сигнализация — это процесс координации связи. Для того чтобы приложение WebRTC могло установить соединение, его клиентам необходимо обменяться следующей информацией:
- Сообщения управления сессией используются для открытия или закрытия связи.
- Сообщения об ошибках
- Метаданные медиафайлов, такие как кодеки, настройки кодеков, пропускная способность и типы медиафайлов.
- Ключевые данные, используемые для установления безопасных соединений
- Сетевые данные, такие как IP-адрес и порт хоста, видимые внешнему миру.
Для этого процесса сигнализации необходим способ обмена сообщениями между клиентами. API WebRTC такой механизм не реализован. Вместо этого вам нужно будет разработать его самостоятельно.
Почему WebRTC не определяет принципы сигнализации?
Во избежание избыточности и для обеспечения максимальной совместимости с существующими технологиями, методы и протоколы сигнализации не определены стандартами WebRTC. Такой подход описан в протоколе установления сеанса JavaScript (JSEP) :
Архитектура JSEP также избавляет браузер от необходимости сохранять состояние, то есть функционировать как конечный автомат сигналов. Это было бы проблематично, если бы, например, данные сигналов терялись при каждой перезагрузке страницы. Вместо этого состояние сигналов может сохраняться на сервере.

JSEP требует обмена между участниками, получающими предложения и ответы , — метаданными медиафайлов. Предложения и ответы передаются в формате протокола описания сессии (SDP), который выглядит следующим образом:
v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2
...
Хотите узнать, что на самом деле означает вся эта тарабарщина SDP? Взгляните на примеры, представленные Инженерной рабочей группой по интернету (IETF) .
Следует помнить, что WebRTC разработан таким образом, что предложение или ответ можно изменить перед установкой в качестве локального или удаленного описания, отредактировав значения в тексте SDP. Например, функция preferAudioCodec() в файле appr.tc может использоваться для установки кодека и битрейта по умолчанию. Манипулирование SDP с помощью JavaScript несколько затруднительно, и ведутся дискуссии о том, следует ли будущим версиям WebRTC использовать JSON вместо него, но у использования SDP есть некоторые преимущества .
API и сигнализация RTCPeerConnection : предложение, ответ и кандидат.
RTCPeerConnection — это API, используемый приложениями WebRTC для установления соединения между участниками и передачи аудио- и видеоданных.
Для инициализации этого процесса RTCPeerConnection выполняет две задачи:
- Уточните локальные условия воспроизведения медиаконтента, такие как разрешение и возможности кодеков. Это метаданные, используемые для механизма «предложение-ответ».
- Получите потенциальные сетевые адреса хоста приложения, известные как кандидаты .
После получения этих локальных данных их необходимо передать удаленному узлу посредством сигнального механизма.
Представьте, что Алиса пытается позвонить Еве . Вот полный механизм ответа во всех его ужасающих подробностях:
- Алиса создает объект
RTCPeerConnection. - Алиса создает предложение (описание сессии SDP) с помощью метода
createOffer()RTCPeerConnection. - Алиса вызывает
setLocalDescription()со своим предложением. - Алиса преобразует предложение в строку и использует сигнальный механизм для его отправки Еве.
- Ева вызывает
setRemoteDescription()с предложением Алисы, чтобы ееRTCPeerConnectionузнал о настройках Алисы. - Ева вызывает функцию
createAnswer(), и в функцию обратного вызова для успешного выполнения передается описание локальной сессии — ответ Евы. - Ева устанавливает свой ответ в качестве локального описания, вызывая
setLocalDescription(). - Затем Ева использует механизм сигнализации, чтобы отправить свой строковый ответ Алисе.
- Алиса устанавливает ответ Евы в качестве описания удаленной сессии, используя
setRemoteDescription().
Алисе и Еве также необходимо обмениваться сетевой информацией. Выражение «поиск кандидатов» относится к процессу поиска сетевых интерфейсов и портов с использованием фреймворка ICE .
- Алиса создает объект
RTCPeerConnectionс обработчикомonicecandidate. - Обработчик вызывается, когда появляются доступные сетевые кандидаты.
- В обработчике Алиса отправляет Еве строковые данные-кандидаты через их сигнальный канал.
- Когда Ева получает сообщение от Алисы с предложением кандидатуры, она вызывает
addIceCandidate()чтобы добавить кандидата в описание удаленного узла.
JSEP поддерживает функцию ICE Candidate Trickling , которая позволяет вызывающей стороне постепенно предоставлять кандидатов вызываемой стороне после первоначального предложения, а вызываемой стороне — начинать действовать в процессе звонка и устанавливать соединение, не дожидаясь поступления всех кандидатов.
Используйте WebRTC для сигнализации.
Приведённый ниже фрагмент кода представляет собой пример кода W3C , который суммирует полный процесс сигнализации. Код предполагает существование некоторого механизма сигнализации, SignalingChannel . Сигнализация более подробно обсуждается далее.
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// send the offer to the other peer
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// After remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
Чтобы увидеть процессы предложения-ответа и обмена кандидатами в действии, посетите simpl.info RTCPeerConnection и посмотрите журнал консоли, чтобы увидеть пример одностраничного видеочата. Вы можете загрузить полный дамп сигналов и статистики WebRTC со страницы about://webrtc-internals в Google Chrome или opera://webrtc-internals в Opera.
Поиск среди коллег
Это витиеватый способ спросить: «Как мне найти человека, с которым можно поговорить?»
Для телефонных звонков вам нужны телефонные номера и телефонные справочники. Для онлайн-видеочата и обмена сообщениями необходимы системы управления идентификацией и присутствием, а также средства для начала сеансов пользователями. Приложениям WebRTC необходим способ, позволяющий клиентам сигнализировать друг другу о желании начать или присоединиться к звонку.
Механизмы обнаружения участников не определены WebRTC, и здесь не рассматриваются их параметры. Процесс может быть очень простым, например, отправка URL-адреса по электронной почте или в мессенджере. В приложениях для видеочата, таких как Talky , tawk.to и Browser Meeting , вы приглашаете людей к звонку, поделившись пользовательской ссылкой. Разработчик Крис Болл создал интересный эксперимент с бессерверным WebRTC , который позволяет участникам звонков WebRTC обмениваться метаданными через любой удобный для них мессенджер, например, мгновенные сообщения, электронную почту или почтовый ящик.
Как можно создать службу сигнализации?
Повторюсь, протоколы и механизмы сигнализации не определены стандартами WebRTC. Что бы вы ни выбрали, вам потребуется промежуточный сервер для обмена сигнальными сообщениями и данными приложения между клиентами. К сожалению, веб-приложение не может крикнуть в интернет: «Подключи меня к моему другу!»
К счастью, сигнальные сообщения небольшие и в основном обмениваются в начале звонка. При тестировании с appr.tc во время видеочата служба сигнализации обработала в общей сложности около 30-45 сообщений, общий размер которых составил около 10 КБ.
Помимо того, что службы сигнализации WebRTC относительно нетребовательны к пропускной способности, они не потребляют много вычислительных ресурсов или памяти, поскольку им нужно только передавать сообщения и хранить небольшой объем данных о состоянии сессии, например, информацию о подключенных клиентах.
Отправка сообщений с сервера на клиент
Служба обмена сообщениями для сигнализации должна быть двунаправленной: от клиента к серверу и от сервера к клиенту. Двунаправленная связь противоречит модели HTTP «запрос/ответ клиент/сервер», однако за многие годы были разработаны различные обходные пути, такие как длительное опросное соединение (long polling ), для передачи данных от службы, работающей на веб-сервере, к веб-приложению, работающему в браузере.
API EventSource позволяет отправлять события с сервера — данные, передаваемые с веб-сервера на клиентский браузер по протоколу HTTP. EventSource предназначен для односторонней передачи сообщений, но его можно использовать в сочетании с XHR для создания сервиса обмена сигнальными сообщениями. Сервис сигнализации передает сообщение от вызывающего абонента, доставленное запросом XHR, через EventSource вызываемому абоненту.
WebSocket предназначен для полнодуплексной связи клиент-сервер, что означает, что сообщения могут передаваться в обоих направлениях одновременно. Одним из преимуществ сигнальной службы, построенной на основе чистого WebSocket или событий, отправляемых сервером ( EventSource ), является то, что бэкэнд для этих API может быть реализован на различных веб-фреймворках, распространенных в большинстве пакетов веб-хостинга для таких языков, как PHP, Python и Ruby.
Все браузеры, поддерживающие WebRTC, также поддерживают WebSocket. Для всех соединений следует использовать TLS , чтобы гарантировать невозможность перехвата сообщений в незашифрованном виде, а также для уменьшения проблем с обходом прокси-сервера . Для получения дополнительной информации о WebSocket и обходе прокси-сервера см. главу о WebRTC в книге Ильи Григорика «Высокопроизводительные сетевые технологии в браузерах» .
Можно организовать передачу сигналов, заставив WebRTC-клиенты многократно опрашивать сервер обмена сообщениями через Ajax, но это приводит к большому количеству избыточных сетевых запросов, что особенно проблематично для мобильных устройств. Даже после установления сессии участникам необходимо опрашивать сервер на наличие сигнальных сообщений в случае изменений или завершения сессии другими участниками. В примере приложения WebRTC Book используется этот вариант с некоторыми оптимизациями частоты опроса.
Масштабная сигнализация
Хотя служба сигнализации потребляет относительно мало полосы пропускания и ресурсов ЦП на одного клиента, серверам сигнализации для популярного приложения, возможно, приходится обрабатывать большое количество сообщений из разных мест с высокой степенью параллелизма. Приложениям WebRTC, обрабатывающим большой трафик, необходимы серверы сигнализации, способные выдерживать значительную нагрузку. Вы не вдаетесь в подробности, но существует ряд вариантов для высокопроизводительной обработки больших объемов сообщений, включая следующие:
Протокол XMPP (eXtensible Messaging and Presence Protocol ) — это протокол, разработанный для обмена мгновенными сообщениями, который может использоваться для сигнализации. Серверные реализации включают ejabberd и Openfire . Клиенты на JavaScript, такие как Strophe.js , используют BOSH для эмуляции двунаправленной потоковой передачи, но BOSH может быть неэффективным и плохо масштабируемым по сравнению с WebSocket.
Библиотеки с открытым исходным кодом, такие как ZeroMQ (используемая TokBox для своего сервиса Rumour ) и OpenMQ ( NullMQ применяет концепции ZeroMQ к веб-платформам, используя протокол STOMP поверх WebSocket).
Коммерческие облачные платформы обмена сообщениями, использующие WebSocket (хотя они могут переключаться на длительное ожидание ответа), такие как Pusher и Kaazing .
Коммерческие платформы WebRTC, такие как vLine.
Создайте службу сигнализации с помощью Socket.io на Node.js.
Ниже приведён код веб-приложения, использующего службу сигнализации, созданную с помощью Socket.io на Node.js. Архитектура Socket.io упрощает создание сервиса для обмена сообщениями, и Socket.io особенно хорошо подходит для сигнализации WebRTC благодаря встроенной концепции комнат. Этот пример предназначен для относительно небольшого числа пользователей, а не для использования в производственной среде.
Socket.io использует WebSocket с резервными вариантами: AJAX long polling, AJAX multipart streaming, Forever Iframe и JSONP polling. Он был портирован на различные бэкенды, но, пожалуй, наиболее известен своей версией для Node.js, используемой в этом примере.
В этом примере WebRTC не используется. Он предназначен для демонстрации того, как интегрировать сигнализацию в веб-приложение. Просмотрите журнал консоли, чтобы увидеть, что происходит, когда клиенты присоединяются к комнате и обмениваются сообщениями. Этот практический пример по WebRTC содержит пошаговые инструкции по интеграции WebRTC в полноценное приложение для видеочата.
Вот файл index.html клиента:
<!DOCTYPE html>
<html>
<head>
<title>WebRTC client</title>
</head>
<body>
<script src='/socket.io/socket.io.js'></script>
<script src='js/main.js'></script>
</body>
</html>
Вот JavaScript-файл main.js , на который ссылается клиент:
const isInitiator;
room = prompt('Enter room name:');
const socket = io.connect();
if (room !== '') {
console.log('Joining room ' + room);
socket.emit('create or join', room);
}
socket.on('full', (room) => {
console.log('Room ' + room + ' is full');
});
socket.on('empty', (room) => {
isInitiator = true;
console.log('Room ' + room + ' is empty');
});
socket.on('join', (room) => {
console.log('Making request to join room ' + room);
console.log('You are the initiator!');
});
socket.on('log', (array) => {
console.log.apply(console, array);
});
Вот полный код серверного приложения:
const static = require('node-static');
const http = require('http');
const file = new(static.Server)();
const app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2013);
const io = require('socket.io').listen(app);
io.sockets.on('connection', (socket) => {
// Convenience function to log server messages to the client
function log(){
const array = ['>>> Message from server: '];
for (const i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', (message) => {
log('Got message:', message);
// For a real app, would be room only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', (room) => {
const numClients = io.sockets.clients(room).length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room ' + room);
if (numClients === 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients === 1) {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
} else { // max two clients
socket.emit('full', room);
}
socket.emit('emit(): client ' + socket.id +
' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id +
' joined room ' + room);
});
});
Для запуска этого приложения на локальном компьютере вам потребуется Node.js , Socket.IO и node-static . Чтобы установить Socket.IO и node-static, запустите npm в терминале в каталоге вашего приложения:
npm install socket.io
npm install node-static
Для запуска сервера выполните следующую команду в терминале в каталоге вашего приложения:
node server.js
Откройте localhost:2013 в браузере. Откройте новую вкладку или окно в любом браузере и снова откройте localhost:2013 . Чтобы посмотреть, что происходит, проверьте консоль. В Chrome и Opera доступ к консоли можно получить через инструменты разработчика Google Chrome с помощью Ctrl+Shift+J (или Command+Option+J на Mac).
Какой бы подход к передаче сигналов вы ни выбрали, ваш бэкэнд и клиентское приложение должны предоставлять услуги, аналогичные приведенному примеру.
Сигнальные подводные камни
-
RTCPeerConnectionне начнет сбор кандидатов, пока не будет вызванsetLocalDescription(). Это предусмотрено в проекте JSEP IETF . - Воспользуйтесь преимуществами Trickle ICE. Вызывайте
addIceCandidate()сразу после появления кандидатов.
Готовые сигнальные серверы
Если вы не хотите разрабатывать собственное решение, существует несколько серверов сигнализации WebRTC, которые используют Socket.IO, как и в предыдущем примере, и интегрированы с клиентскими библиотеками JavaScript WebRTC:
- webRTC.io — одна из первых библиотек абстракции для WebRTC.
- Signalmaster — это сервер сигнализации, созданный для использования с клиентской библиотекой JavaScript SimpleWebRTC .
Если вы вообще не хотите писать код, то готовые коммерческие платформы WebRTC доступны от таких компаний, как vLine , OpenTok и Asterisk .
К слову, компания Ericsson в начале развития WebRTC создала сервер сигнализации на PHP под управлением Apache . Сейчас он несколько устарел, но стоит ознакомиться с кодом, если вы рассматриваете возможность внедрения чего-то подобного.
Безопасность сигналов
Шифрование является обязательным для всех компонентов WebRTC.
Однако механизмы сигнализации не определены стандартами WebRTC, поэтому обеспечение безопасности сигнализации — ваша задача. Если злоумышленнику удастся перехватить сигнализацию, он сможет остановить сессии, перенаправить соединения, а также записывать, изменять или внедрять контент.
Наиболее важным фактором обеспечения безопасности сигнализации является использование защищенных протоколов: HTTPS и WSS, таких как TLS. Это гарантирует невозможность перехвата незашифрованных сообщений. Также следует избегать трансляции сигнальных сообщений таким образом, чтобы к ним могли получить доступ другие абоненты, использующие тот же сигнальный сервер.
Как справиться с NAT и брандмауэрами
Для передачи метаданных приложения WebRTC используют промежуточный сервер, но для фактической потоковой передачи мультимедиа и данных после установления сеанса RTCPeerConnection пытается подключить клиентов напрямую или по принципу peer-to-peer.
В более простом мире каждая конечная точка WebRTC имела бы уникальный адрес, которым она могла бы обмениваться с другими участниками для прямой связи.

В действительности большинство устройств находятся за одним или несколькими уровнями NAT , некоторые имеют антивирусное программное обеспечение, блокирующее определенные порты и протоколы, а многие находятся за прокси-серверами и корпоративными брандмауэрами. Брандмауэр и NAT могут быть реализованы одним и тем же устройством, например, домашним Wi-Fi-роутером.

Приложения WebRTC могут использовать фреймворк ICE для преодоления сложностей реальных сетевых взаимодействий. Для этого ваше приложение должно передавать URL-адреса ICE-серверов в RTCPeerConnection .
ICE пытается найти оптимальный путь для подключения узлов. Он параллельно перебирает все возможные варианты и выбирает наиболее эффективный из них. Сначала ICE пытается установить соединение, используя адрес хоста, полученный из операционной системы и сетевой карты устройства. Если это не удаётся (что произойдёт с устройствами, находящимися за NAT), ICE получает внешний адрес с помощью STUN-сервера, и если и это не удаётся, трафик маршрутизируется через TURN-сервер ретрансляции.
Иными словами, STUN-сервер используется для получения внешнего сетевого адреса, а TURN-серверы — для ретрансляции трафика в случае сбоя прямого (однорангового) соединения.
Каждый TURN-сервер поддерживает STUN. TURN-сервер — это STUN-сервер с дополнительной встроенной функцией ретрансляции. ICE также справляется со сложностями настройки NAT. В действительности, для пробития NAT-дыры может потребоваться нечто большее, чем просто публичный IP-адрес:порт.
URL-адреса для STUN и TURN серверов (опционально) указываются приложением WebRTC в объекте конфигурации iceServers , который является первым аргументом конструктора RTCPeerConnection . Для appr.tc это значение выглядит следующим образом:
{
'iceServers': [
{
'urls': 'stun:stun.l.google.com:19302'
},
{
'urls': 'turn:192.158.29.39:3478?transport=udp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
},
{
'urls': 'turn:192.158.29.39:3478?transport=tcp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
}
]
}
Как только RTCPeerConnection получит эту информацию, магия ICE начнет работать автоматически. RTCPeerConnection использует фреймворк ICE для определения оптимального пути между узлами, взаимодействуя при необходимости с серверами STUN и TURN.
ОГЛУШЕНИЕ
NAT предоставляет устройству IP-адрес для использования внутри частной локальной сети, но этот адрес нельзя использовать за пределами сети. Без публичного адреса у участников WebRTC нет возможности взаимодействовать. Для решения этой проблемы WebRTC использует STUN .
STUN-серверы находятся в общедоступном интернете и выполняют одну задачу: проверяют IP-адрес и порт входящего запроса (от приложения, работающего за NAT) и отправляют этот адрес обратно в качестве ответа. Другими словами, приложение использует STUN-сервер для определения своего IP-адреса и порта с общедоступной точки зрения. Этот процесс позволяет участнику WebRTC получить общедоступный адрес для себя, а затем передать его другому участнику через механизм сигнализации для установления прямой связи.
STUN-серверам не нужно выполнять много действий или запоминать много информации, поэтому STUN-серверы с относительно низкими характеристиками могут обрабатывать большое количество запросов.
В большинстве случаев WebRTC-звонки успешно устанавливают соединение с использованием STUN, хотя это может происходить реже при звонках между узлами за брандмауэрами и в сложных конфигурациях NAT.

ПОВЕРНУТЬ
RTCPeerConnection пытается установить прямую связь между узлами по протоколу UDP. Если это не удаётся, RTCPeerConnection переходит на TCP. В этом случае в качестве резервного варианта можно использовать TURN-серверы, передающие данные между конечными точками.
Ещё раз подчеркну, что TURN используется для передачи аудио, видео и потоковых данных между участниками, а не для передачи сигналов данных!
Серверы TURN имеют публичные адреса, поэтому к ним могут обращаться другие участники сети, даже если те находятся за брандмауэрами или прокси-серверами. Задача серверов TURN одна: ретрансляция потока. В отличие от серверов STUN, они по своей природе потребляют много полосы пропускания.

На этой диаграмме показана работа TURN. Чистый STUN не сработал, поэтому каждый участник сети переходит к использованию TURN-сервера.
Развертывание STUN- и TURN-серверов
Для тестирования Google использует общедоступный STUN-сервер stun.l.google.com:19302 , аналогичный используемому в appr.tc. Для работы в производственной среде используйте rfc5766-turn-server. Исходный код STUN и TURN-серверов доступен на GitHub , где также можно найти ссылки на различные источники информации об установке серверов. Также доступен образ виртуальной машины для Amazon Web Services .
Альтернативным TURN-сервером является restund, доступный как в виде исходного кода , так и для AWS. Вы можете настроить restund на Compute:
- При необходимости откройте брандмауэр для tcp=443, udp/tcp=3478.
- Создайте четыре экземпляра, по одному для каждого публичного IP-адреса, используя стандартный образ Ubuntu 12.06.
- Настройте локальную конфигурацию брандмауэра (разрешите ANY из ANY).
- Установка инструментов:
shell sudo apt-get install make sudo apt-get install gcc - Установите LibreOffice с сайта creytiv.com/re.html .
- Загрузите файл restund с сайта creytiv.com/restund.html и распакуйте его.
-
wgethancke.name/restund-auth.patch и примените ее с помощьюpatch -p1 < restund-auth.patch. - Выполните команды
makeиsudo make installдля получения версий LibreOffice и Restund. - Адаптируйте
restund.confпод свои нужды (замените IP-адреса и убедитесь, что он содержит тот же общий секретный ключ) и скопируйте его в/etc. - Скопируйте
restund/etc/restundв/etc/init.d/. - Настройка возврата средств:
- Установите
LD_LIBRARY_PATH. - Скопируйте
restund.confв/etc/restund.conf. - В файле
restund.confукажите правильный IP-адрес (10).
- Установите
- Run restund
- Проверка с использованием клиента stund с удаленной машины:
./client IP:port
Многосторонний WebRTC
Возможно, вам также будет интересно ознакомиться с предложенным Джастином Уберти стандартом IETF для REST API для доступа к сервисам TURN .
Существует множество вариантов использования потоковой передачи мультимедиа, выходящих за рамки личного звонка. Например, видеоконференции между группой коллег или публичные мероприятия с одним докладчиком и сотнями или миллионами зрителей.
Приложение WebRTC может использовать несколько RTCPeerConnections, так что каждая конечная точка подключается ко всем остальным конечным точкам в конфигурации mesh. Именно такой подход используют такие приложения, как talky.io , и он отлично работает для небольшого количества участников сети. В дальнейшем потребление вычислительных ресурсов и полосы пропускания становится чрезмерным, особенно для мобильных клиентов.

В качестве альтернативы, приложение WebRTC может выбрать одну конечную точку для распространения потоков на все остальные в конфигурации «звезда». Также можно запустить конечную точку WebRTC на сервере и создать собственный механизм перераспределения ( пример клиентского приложения предоставлен на webrtc.org).
MediaStream из одного RTCPeerConnection может использоваться в качестве входных данных для другого. Это позволяет создавать более гибкие архитектуры, поскольку веб-приложение может обрабатывать маршрутизацию вызовов, выбирая, к какому другому узлу подключиться. Чтобы увидеть это в действии, см. примеры WebRTC Peer connection relay и WebRTC Multiple peer connections .
Многоточечный блок управления
Для большого количества конечных точек лучше использовать многоточечный блок управления (MCU). Это сервер, который работает как мост для распределения медиаданных между большим количеством участников. MCU могут обрабатывать различные разрешения, кодеки и частоту кадров в видеоконференции; выполнять транскодирование; осуществлять выборочную пересылку потоков; а также микшировать или записывать аудио и видео. Для многосторонних звонков необходимо учитывать ряд вопросов, в частности, как отображать несколько видеовходов и микшировать аудио из нескольких источников. Облачные платформы, такие как vLine , также пытаются оптимизировать маршрутизацию трафика.
Можно приобрести готовый комплект микроконтроллера или собрать его самостоятельно.

Существует несколько вариантов программного обеспечения для микроконтроллеров с открытым исходным кодом. Например, Licode (ранее известная как Lynckia) выпускает микроконтроллер с открытым исходным кодом для WebRTC. У OpenTok есть Mantis .
Помимо браузеров: VoIP, телефоны и мессенджеры.
Стандартизированный характер WebRTC позволяет устанавливать связь между WebRTC-приложением, работающим в браузере, и устройством или платформой, работающей на другой коммуникационной платформе, например, телефоном или системой видеоконференцсвязи.
SIP — это протокол сигнализации, используемый системами VoIP и видеоконференцсвязи. Для обеспечения связи между веб-приложением WebRTC и SIP-клиентом, например, системой видеоконференцсвязи, WebRTC необходим прокси-сервер для передачи сигналов. Сигналы должны проходить через шлюз, но после установления связи трафик SRTP (видео и аудио) может передаваться напрямую между узлами сети.
Общедоступная телефонная сеть (PSTN) — это сеть с коммутацией каналов , в которой используются все «старые добрые» аналоговые телефоны. Для звонков между веб-приложениями WebRTC и телефонами трафик должен проходить через шлюз PSTN. Аналогично, веб-приложениям WebRTC необходим промежуточный XMPP-сервер для связи с конечными точками Jingle , такими как клиенты мгновенных сообщений. Jingle был разработан Google как расширение XMPP для обеспечения голосовой и видеосвязи для служб обмена сообщениями. Текущие реализации WebRTC основаны на библиотеке C++ libjingle , реализации Jingle, первоначально разработанной для Talk.
Ряд приложений, библиотек и платформ используют возможности WebRTC для связи с внешним миром. Например:
- jsSIP : Библиотека JavaScript для работы с протоколом SIP
- Phono : API для телефонии на JavaScript с открытым исходным кодом, реализованный в виде плагина.
- Twilio : голосовая связь и обмен сообщениями
Узнать больше
- Ознакомьтесь с документацией по API WebRTC .
- В практическом руководстве по WebRTC представлены пошаговые инструкции по созданию приложения для видео- и текстового чата с использованием сервиса сигнализации Socket.io, работающего на Node.js.
- Презентация Криса Уилсона о SFHTML5: Введение в приложения WebRTC.
В 350-страничной книге WebRTC: API и протоколы RTCWEB сети реального времени HTML5 содержится много подробной информации о путях передачи данных и сигналов, а также ряд подробных схем сетевой топологии.