Дата публикации: 4 ноября 2013 г.
WebRTC обеспечивает одноранговое подключение. Для обмена метаданными и координации связи между клиентами требуются серверы. Этот процесс называется сигнализацией. Серверы также помогают клиентам справляться с преобразователями сетевых адресов (NAT) и брандмауэрами.
Вы узнаете, как создать службу сигнализации и как работать с серверами STUN и TURN. Вы также узнаете, как приложения WebRTC могут обрабатывать многосторонние вызовы и взаимодействовать с такими сервисами, как VoIP и PSTN (также известными как телефоны).
Что такое сигнализация?
Сигнализация – это процесс координации связи. Чтобы приложение WebRTC могло установить вызов, его клиенты должны обменяться следующей информацией:
- Сообщения для управления сеансом, используемые для открытия или закрытия связи.
- Сообщения об ошибках
- метаданные медиаконтента, например кодеки, настройки кодеков, пропускная способность и типы медиаконтента;
- Ключевые данные, используемые для установки защищенных подключений.
- Сетевые данные, например IP-адрес и порт хоста, видимые извне.
Для этого клиентам нужен способ обмениваться сообщениями. Этот механизм не реализован в API WebRTC. Вместо этого вам нужно построить его самостоятельно.
Почему сигнализация не определена WebRTC?
Чтобы избежать избыточности и обеспечить максимальную совместимость с устоявшимися технологиями, методы и протоколы сигнализации не указаны в стандартах WebRTC. Этот подход описан в протоколе JSEP (JavaScript Session Establishment Protocol):
Архитектура 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 есть некоторые преимущества.
RTCPeerConnection API и сигналы: предложение, ответ и кандидат
RTCPeerConnection – это API, который используется приложениями WebRTC для создания соединения между узлами и передачи аудио и видео.
Чтобы запустить этот процесс, RTCPeerConnection выполняет две задачи:
- Определите локальные условия медиа, такие как разрешение и возможности кодека. Это метаданные, используемые для механизма предложения и ответа.
- Получить потенциальные сетевые адреса для хоста приложения, известные как кандидаты.
После того, как эти локальные данные будут установлены, они должны быть обменены через механизм сигнализации с удаленным узлом.
Представьте, что Алиса пытается позвонить Еве. Вот как работает механизм ответа во всех подробностях:
- Алиса создает объект
RTCPeerConnection. - Алиса создает предложение (описание сеанса SDP) с помощью метода
RTCPeerConnectioncreateOffer(). - Алиса звонит в компанию
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, вы приглашаете людей на звонок, отправляя им специальную ссылку. Разработчик Крис Болл (Chris Ball) создал интересный экспериментальный проект serverless-webrtc, который позволяет участникам вызова WebRTC обмениваться метаданными с помощью любого сервиса обмена сообщениями, например IM, электронной почты или почтовых голубей.
Как создать сервис сигнализации?
Повторим, что протоколы и механизмы сигнализации не определены стандартами WebRTC. В любом случае вам понадобится промежуточный сервер для обмена сигнальными сообщениями и данными приложений между клиентами. К сожалению, веб-приложение не может крикнуть в интернет: "Подключи меня к моему другу!"
К счастью, сигнальные сообщения невелики и в основном передаются в начале вызова. При тестировании видеочата с помощью appr.tc сервис сигнализации обработал 30–45 сообщений общим размером около 10 КБ.
Помимо относительно невысоких требований к пропускной способности, сервисы сигнализации WebRTC не потребляют много вычислительных ресурсов или памяти, поскольку им нужно только передавать сообщения и сохранять небольшой объем данных о состоянии сеанса, например о том, какие клиенты подключены.
Отправка push-уведомлений с сервера на клиент
Служба обмена сообщениями для сигнализации должна быть двунаправленной: клиент-сервер и сервер-клиент. Двунаправленная связь противоречит модели "запрос/ответ" для HTTP-клиента и сервера, но за многие годы были разработаны различные обходные пути, такие как длинный опрос, позволяющие передавать данные из сервиса, работающего на веб-сервере, в веб-приложение, работающее в браузере.
EventSource API позволяет отправлять события с сервера, то есть передавать данные с веб-сервера в браузер клиента по протоколу HTTP. EventSource предназначен для одностороннего обмена сообщениями, но его можно использовать в сочетании с XHR для создания сервиса обмена сигнальными сообщениями. Сигнальный сервис передает сообщение от вызывающего абонента, доставленное с помощью XHR-запроса, отправляя его через EventSource вызываемому абоненту.
WebSocket предназначен для дуплексной связи между клиентом и сервером, то есть сообщения могут передаваться в обоих направлениях одновременно. Преимущество сервиса сигнализации, созданного с помощью чистого WebSocket или событий, отправляемых сервером (EventSource), заключается в том, что серверная часть для этих API может быть реализована на различных веб-фреймворках, общих для большинства пакетов веб-хостинга для таких языков, как PHP, Python и Ruby.
Все браузеры, поддерживающие WebRTC, также поддерживают WebSocket. Для всех подключений следует использовать TLS, чтобы сообщения не могли быть перехвачены в незашифрованном виде, а также чтобы уменьшить количество проблем с обходом прокси-серверов. Дополнительную информацию о WebSocket и обходе прокси-серверов можно найти в главе о WebRTC книги Ильи Григорика High Performance Browser Networking.
Вы можете обрабатывать сигналы, заставляя клиентов WebRTC многократно опрашивать сервер обмена сообщениями через Ajax, но это приводит к большому количеству избыточных сетевых запросов, что особенно проблематично для мобильных устройств. Даже после установления сеанса узлы должны опрашивать сигнальные сообщения на случай изменений или завершения сеанса другими узлами. Пример приложения WebRTC Book использует этот вариант с некоторыми оптимизациями частоты опроса.
Масштабирование сигналов
Хотя сервис сигнализации потребляет относительно небольшую пропускную способность и ресурсы ЦП на одного клиента, серверы сигнализации для популярного приложения могут обрабатывать множество сообщений из разных мест с высоким уровнем параллелизма. Приложениям WebRTC с большим объемом трафика требуются сигнальные серверы, способные справляться со значительной нагрузкой. Вы не вдаетесь в подробности, но существует ряд вариантов для обмена сообщениями с большим объемом и высокой производительностью, в том числе следующие:
eXtensible Messaging and Presence Protocol (XMPP) – это протокол, разработанный для обмена мгновенными сообщениями, который можно использовать для передачи сигналов. Примеры реализации сервера: ejabberd и Openfire. Клиенты JavaScript, такие как Strophe.js, используют BOSH для эмуляции двунаправленной потоковой передачи, но BOSH может быть неэффективным и плохо масштабируемым по сравнению с WebSocket.
Библиотеки с открытым исходным кодом, такие как ZeroMQ (используется TokBox для сервиса Rumour) и OpenMQ (NullMQ применяет концепции ZeroMQ к веб-платформам, используя протокол STOMP через WebSocket).
Коммерческие платформы для обмена сообщениями в облаке, использующие WebSocket (хотя они могут возвращаться к длинным опросам), такие как Pusher и Kaazing.
Коммерческие платформы WebRTC, например vLine.
Создание сервиса сигнализации с помощью Socket.io на Node
Ниже приведен код веб-приложения, которое использует сервис сигнализации, созданный с помощью Socket.io на Node. Дизайн Socket.io упрощает создание сервиса для обмена сообщениями, а Socket.io особенно подходит для сигнализации WebRTC из-за встроенной концепции комнат. Этот пример предназначен для относительно небольшого числа пользователей, а не для рабочей среды.
Socket.io использует WebSocket с резервными вариантами: длинный опрос AJAX, многокомпонентная потоковая передача AJAX, Forever Iframe и опрос JSONP. Она была перенесена на различные серверные части, но, пожалуй, наиболее известна своей версией Node, используемой в этом примере.
В этом примере WebRTC не используется. Он показывает, как встроить сигнализацию в веб-приложение. Посмотрите журнал консоли, чтобы узнать, что происходит, когда клиенты присоединяются к комнате и обмениваются сообщениями. В практической работе по WebRTC приведены пошаговые инструкции по интеграции этого API в приложение для видеочата на основе 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.
Кстати, в первые дни существования WebRTC компания Ericsson создала сервер сигнализации, используя PHP на Apache. Сейчас он несколько устарел, но если вы планируете создать что-то подобное, то можете ознакомиться с его кодом.
Безопасность Signal
Шифрование обязательно для всех компонентов WebRTC.
Однако механизмы сигнализации не определены стандартами WebRTC, поэтому вы должны обеспечить безопасность сигнализации. Если злоумышленнику удастся перехватить сигналы, он сможет останавливать сеансы, перенаправлять подключения, а также записывать, изменять или внедрять контент.
Самый важный фактор в обеспечении безопасности сигнализации – использование защищенных протоколов: HTTPS и WSS, например TLS. Это гарантирует, что сообщения не будут перехвачены в незашифрованном виде. Также будьте осторожны, чтобы не транслировать сигнальные сообщения таким образом, чтобы к ним могли получить доступ другие абоненты, использующие тот же сигнальный сервер.
Работа с NAT и брандмауэрами
Для передачи метаданных приложения WebRTC используют промежуточный сервер, но для потоковой передачи медиаконтента и данных после установления сеанса RTCPeerConnection пытается подключить клиентов напрямую или по одноранговой сети.
В более простом мире каждая конечная точка 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 не выполняют сложных операций и не хранят много данных, поэтому даже серверы с относительно низкими характеристиками могут обрабатывать большое количество запросов.
Большинство вызовов 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. Для рабочей версии сервиса STUN/TURN используйте rfc5766-turn-server. Исходный код для серверов STUN и TURN доступен на сайте GitHub, где также можно найти ссылки на несколько источников информации об установке серверов. Также доступен образ виртуальной машины для Amazon Web Services.
В качестве альтернативы можно использовать TURN-сервер restund, доступный в виде исходного кода, а также для AWS. Вы можете настроить restund на Compute :
- При необходимости откройте брандмауэр для tcp=443, udp/tcp=3478.
- Создайте четыре экземпляра, по одному для каждого общедоступного IP-адреса, со стандартным образом Ubuntu 12.06.
- Настройте локальный брандмауэр (разрешите любые подключения).
- Установите инструменты:
shell sudo apt-get install make sudo apt-get install gcc - Установите libre с сайта creytiv.com/re.html.
- Скачайте restund с сайта creytiv.com/restund.html и распакуйте.
wgethancke.name/restund-auth.patch и примените с помощьюpatch -p1 < restund-auth.patch.- Запустите
make,sudo make installдля libre и restund. - Адаптируйте
restund.confпод свои нужды (замените IP-адреса и убедитесь, что он содержит тот же общий секрет) и скопируйте в/etc. - Скопируйте
restund/etc/restundв/etc/init.d/. - Настройте restund:
- Установите значение
LD_LIBRARY_PATH. - Скопируйте
restund.confв/etc/restund.conf. - Задайте для
restund.confзначение 10. IP-адрес.
- Установите значение
- Запустите restund
- Протестируйте с помощью клиента stund с удаленного компьютера:
./client IP:port
Многосторонний WebRTC
Вы также можете ознакомиться с предложенным Джастином Уберти (Justin Uberti) стандартом IETF для REST API для доступа к сервисам TURN.
Потоковая передача медиаконтента используется не только для звонков между двумя пользователями. Например, это может быть видеоконференция с коллегами или публичное мероприятие с одним докладчиком и сотнями или миллионами зрителей.
Приложение WebRTC может использовать несколько RTCPeerConnection, чтобы каждая конечная точка подключалась к каждой другой конечной точке в ячеистой конфигурации. Этот подход используется в таких приложениях, как talky.io, и отлично работает для небольшого количества участников. В противном случае обработка и потребление пропускной способности будут чрезмерными, особенно для мобильных клиентов.
В качестве альтернативы приложение WebRTC может выбрать одну конечную точку для распределения потоков по всем остальным в конфигурации звезды. Вы также можете запустить конечную точку WebRTC на сервере и создать собственный механизм перераспределения (пример клиентского приложения можно найти на сайте webrtc.org).
MediaStream из одного RTCPeerConnection можно использовать в качестве входных данных для другого. Это позволяет создавать более гибкие архитектуры, поскольку веб-приложение может управлять маршрутизацией вызовов, выбирая, к какому другому узлу подключаться. Чтобы посмотреть, как это работает, ознакомьтесь с примерами Peer connection relay (Ретрансляция однорангового подключения) и Multiple peer connections (Несколько одноранговых подключений).
Блок многоточечного управления
Для большого количества конечных точек лучше использовать блок многоточечного управления (MCU). Это сервер, который работает как мост для распределения медиаданных между большим количеством участников. MCU могут работать с разными разрешениями, кодеками и частотой кадров в видеоконференции, выполнять транскодирование, выборочную переадресацию потоков, а также микшировать или записывать аудио и видео. Для многосторонних вызовов существует ряд проблем, которые необходимо учитывать, в частности, как отображать несколько видеовходов и микшировать аудио из нескольких источников. Облачные платформы, такие как vLine, также пытаются оптимизировать маршрутизацию трафика.
Вы можете купить готовый комплект оборудования MCU или собрать его самостоятельно.
Существует несколько вариантов ПО с открытым исходным кодом для MCU. Например, Licode (ранее – Lynckia) создает MCU с открытым исходным кодом для WebRTC. В OpenTok есть Mantis.
Не только браузеры: VoIP, телефоны и обмен сообщениями
Стандартизированный характер WebRTC позволяет установить связь между приложением WebRTC, работающим в браузере, и устройством или платформой, работающей на другой коммуникационной платформе, например телефоном или системой видеоконференций.
SIP – это сигнальный протокол, используемый системами VoIP и видеоконференций. Чтобы обеспечить связь между веб-приложением WebRTC и SIP-клиентом, например системой видеоконференций, WebRTC требуется прокси-сервер для передачи сигналов. Сигналы должны проходить через шлюз, но после установления связи трафик SRTP (видео и аудио) может передаваться по одноранговой сети.
Телефонная сеть общего пользования (PSTN) – это коммутируемая сеть всех обычных аналоговых телефонов. Для звонков между веб-приложениями WebRTC и телефонами трафик должен проходить через шлюз PSTN. Аналогично, веб-приложениям WebRTC нужен промежуточный сервер XMPP для связи с конечными точками Jingle, такими как клиенты IM. Jingle – это разработанное Google расширение для XMPP, которое позволяет использовать голосовую и видеосвязь в сервисах обмена сообщениями. Текущие реализации WebRTC основаны на библиотеке C++ libjingle, которая изначально была разработана для Talk.
Многие приложения, библиотеки и платформы используют возможности WebRTC для связи с внешним миром. Пример:
- jsSIP – библиотека SIP на JavaScript.
- Phono – API для телефонии на базе JavaScript с открытым исходным кодом, созданный как плагин.
- Twilio – голосовые вызовы и обмен сообщениями.
Подробнее
- Ознакомьтесь с документацией по WebRTC API.
- В практической работе по WebRTC приведены пошаговые инструкции по созданию приложения для видео- и текстового чата с использованием службы сигнализации Socket.io, работающей на Node.
- Презентация Криса Уилсона на SFHTML5: Введение в приложения WebRTC
В 350-страничной книге WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web подробно описаны пути передачи данных и сигналов, а также приведено множество схем топологии сети.