Apa yang dimaksud dengan sinyal?
Sinyal adalah proses koordinasi komunikasi. Agar aplikasi WebRTC dapat menyiapkan panggilan, kliennya harus bertukar informasi berikut:
- Pesan kontrol sesi yang digunakan untuk membuka atau menutup komunikasi
- Pesan error
- Metadata media, seperti codec, setelan codec, bandwidth, dan jenis media
- Data kunci yang digunakan untuk membuat koneksi aman
- Data jaringan, seperti alamat IP dan port host seperti yang dilihat oleh dunia luar
Proses sinyal ini memerlukan cara bagi klien untuk meneruskan pesan bolak-balik. Mekanisme tersebut tidak diimplementasikan oleh WebRTC API. Anda harus membuatnya sendiri. Nanti dalam artikel ini, Anda akan mempelajari cara membuat layanan sinyal. Namun, pertama-tama, Anda memerlukan sedikit konteks.
Mengapa sinyal tidak ditentukan oleh WebRTC?
Untuk menghindari redundansi dan memaksimalkan kompatibilitas dengan teknologi yang sudah ada, metode dan protokol sinyal tidak ditentukan oleh standar WebRTC. Pendekatan ini diuraikan oleh JavaScript Session Establishment Protocol (JSEP):
Arsitektur JSEP juga menghindari browser yang harus menyimpan status, yaitu berfungsi sebagai mesin status sinyal. Hal ini akan menjadi masalah jika, misalnya, data sinyal hilang setiap kali halaman dimuat ulang. Sebagai gantinya, status sinyal dapat disimpan di server.
JSEP memerlukan pertukaran antara peer offer dan answer, metadata media yang disebutkan di atas. Penawaran dan jawaban dikomunikasikan dalam format Session Description Protocol (SDP), yang terlihat seperti ini:
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
…
Ingin tahu apa arti semua omong kosong SDP ini? Lihat contoh Internet Engineering Task Force (IETF).
Perlu diingat bahwa WebRTC dirancang agar penawaran atau jawaban dapat disesuaikan sebelum ditetapkan sebagai deskripsi lokal atau jarak jauh dengan mengedit nilai dalam teks SDP. Misalnya, fungsi preferAudioCodec()
di appr.tc dapat digunakan untuk menetapkan codec dan kecepatan bit default. SDP agak sulit dimanipulasi dengan JavaScript dan ada diskusi tentang apakah versi WebRTC mendatang harus menggunakan JSON, tetapi ada beberapa keuntungan untuk tetap menggunakan SDP.
RTCPeerConnection
API dan sinyal: Penawaran, jawaban, dan kandidat
RTCPeerConnection
adalah API yang digunakan oleh aplikasi WebRTC untuk membuat koneksi antar-peer, serta berkomunikasi dengan audio dan video.
Untuk melakukan inisialisasi proses ini, RTCPeerConnection
memiliki dua tugas:
- Pastikan kondisi media lokal, seperti resolusi dan kemampuan codec. Ini adalah metadata yang digunakan untuk mekanisme penawaran dan jawaban.
- Mendapatkan alamat jaringan potensial untuk host aplikasi, yang dikenal sebagai kandidat.
Setelah data lokal ini dipastikan, data tersebut harus dipertukarkan melalui mekanisme sinyal dengan peer jarak jauh.
Bayangkan Anita mencoba menelepon Eva. Berikut adalah mekanisme penawaran/jawaban lengkap beserta semua detailnya yang mengerikan:
- Alice membuat objek
RTCPeerConnection
. - Alice membuat penawaran (deskripsi sesi SDP) dengan metode
RTCPeerConnection
createOffer()
. - Alice menelepon
setLocalDescription()
dengan penawarannya. - Alice membuat string penawaran dan menggunakan mekanisme sinyal untuk mengirimkannya ke Eve.
- Eve memanggil
setRemoteDescription()
dengan penawaran Alice, sehinggaRTCPeerConnection
-nya mengetahui penyiapan Alice. - Eve memanggil
createAnswer()
dan callback sukses untuk ini diteruskan deskripsi sesi lokal - jawaban Eve. - Eve menetapkan jawabannya sebagai deskripsi lokal dengan memanggil
setLocalDescription()
. - Eve kemudian menggunakan mekanisme sinyal untuk mengirim jawaban string-nya ke Alice.
- Alice menetapkan jawaban Eve sebagai deskripsi sesi jarak jauh menggunakan
setRemoteDescription()
.
Alice dan Eve juga perlu bertukar informasi jaringan. Ekspresi "menemukan kandidat" mengacu pada proses menemukan antarmuka dan port jaringan menggunakan framework ICE.
- Alice membuat objek
RTCPeerConnection
dengan pengendalionicecandidate
. - Pengendali dipanggil saat kandidat jaringan tersedia.
- Di pengendali, Alice mengirim data kandidat yang di-string ke Eve melalui saluran sinyal mereka.
- Saat Eve mendapatkan pesan kandidat dari Alice, ia memanggil
addIceCandidate()
untuk menambahkan kandidat ke deskripsi peer jarak jauh.
JSEP mendukung ICE Candidate Trickling, yang memungkinkan pemanggil memberikan kandidat secara bertahap kepada penerima setelah penawaran awal, dan penerima dapat mulai menindaklanjuti panggilan dan menyiapkan koneksi tanpa menunggu semua kandidat tiba.
Membuat kode WebRTC untuk sinyal
Cuplikan kode berikut adalah contoh kode W3C yang merangkum proses sinyal lengkap. Kode mengasumsikan adanya beberapa mekanisme sinyal, SignalingChannel
. Sinyal akan dibahas secara lebih mendetail nanti.
// 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);
}
};
Untuk melihat proses penawaran/jawaban dan pertukaran kandidat, lihat simpl.info RTCPeerConnection dan lihat log konsol untuk contoh chat video satu halaman. Jika Anda menginginkan lebih banyak informasi, download dump lengkap sinyal dan statistik WebRTC dari halaman about://webrtc-internals di Google Chrome atau halaman opera://webrtc-internals di Opera.
Penemuan peer
Ini adalah cara elegan untuk bertanya, "Bagaimana cara menemukan seseorang untuk diajak bicara?"
Untuk panggilan telepon, Anda memiliki nomor telepon dan direktori. Untuk chat video dan pesan online, Anda memerlukan sistem pengelolaan identitas dan kehadiran, serta cara bagi pengguna untuk memulai sesi. Aplikasi WebRTC memerlukan cara bagi klien untuk saling memberi sinyal bahwa mereka ingin memulai atau bergabung ke panggilan.
Mekanisme penemuan peer tidak ditentukan oleh WebRTC dan Anda tidak perlu masuk ke opsi di sini. Prosesnya dapat semudah mengirim email atau pesan URL. Untuk aplikasi video chat, seperti Talky, tawk.to, dan Browser Meeting, Anda dapat mengundang orang ke panggilan dengan membagikan link kustom. Developer Chris Ball membuat eksperimen serverless-webrtc yang menarik yang memungkinkan peserta panggilan WebRTC untuk bertukar metadata melalui layanan pesan apa pun yang mereka sukai, seperti IM, email, atau merpati pos.
Bagaimana cara membuat layanan sinyal?
Untuk mengulangi, protokol dan mekanisme sinyal tidak ditentukan oleh standar WebRTC. Apa pun yang Anda pilih, Anda memerlukan server perantara untuk bertukar pesan sinyal dan data aplikasi antar-klien. Sayangnya, aplikasi web tidak dapat langsung berteriak ke internet, "Hubungkan saya ke teman saya".
Untungnya, pesan sinyal berukuran kecil dan sebagian besar dipertukarkan di awal panggilan. Dalam pengujian dengan appr.tc untuk sesi video chat, total sekitar 30-45 pesan ditangani oleh layanan sinyal dengan ukuran total untuk semua pesan sekitar 10 KB.
Selain relatif tidak menuntut dalam hal bandwidth, layanan sinyal WebRTC tidak menghabiskan banyak pemrosesan atau memori karena hanya perlu meneruskan pesan dan menyimpan sejumlah kecil data status sesi, seperti klien mana yang terhubung.
Mengirim pesan push dari server ke klien
Layanan pesan untuk sinyal harus bersifat dua arah: klien ke server dan server ke klien. Komunikasi dua arah bertentangan dengan model permintaan/respons klien/server HTTP, tetapi berbagai hack seperti long polling telah dikembangkan selama bertahun-tahun untuk mendorong data dari layanan yang berjalan di server web ke aplikasi web yang berjalan di browser.
Baru-baru ini, EventSource
API telah diterapkan secara luas. Hal ini memungkinkan peristiwa yang dikirim server - data yang dikirim dari server web ke klien browser melalui HTTP. EventSource
dirancang untuk pesan satu arah, tetapi dapat digunakan bersama dengan XHR untuk membuat layanan guna bertukar pesan sinyal. Layanan sinyal meneruskan pesan dari pemanggil, yang dikirim oleh permintaan XHR, dengan mendorongnya melalui EventSource
ke pemanggil.
WebSocket adalah solusi yang lebih alami, yang dirancang untuk komunikasi klien–server full duplex - pesan yang dapat mengalir dalam kedua arah secara bersamaan. Salah satu keunggulan layanan sinyal yang dibuat dengan WebSocket murni atau peristiwa yang dikirim server (EventSource
) adalah backend untuk API ini dapat diterapkan di berbagai framework web yang umum digunakan oleh sebagian besar paket hosting web untuk bahasa seperti PHP, Python, dan Ruby.
Semua browser modern kecuali Opera Mini mendukung WebSocket dan, yang lebih penting, semua browser yang mendukung WebRTC juga mendukung WebSocket, baik di desktop maupun seluler. TLS harus digunakan untuk semua koneksi untuk memastikan pesan tidak dapat disadap tanpa dienkripsi dan juga untuk mengurangi masalah terkait traversal proxy. (Untuk mengetahui informasi selengkapnya tentang WebSocket dan traversal proxy, lihat bab WebRTC di High Performance Browser Networking karya Ilya Grigorik.)
Anda juga dapat menangani sinyal dengan meminta klien WebRTC untuk melakukan polling server pesan berulang kali melalui Ajax, tetapi hal itu menyebabkan banyak permintaan jaringan yang redundan, yang terutama bermasalah untuk perangkat seluler. Bahkan setelah sesi dibuat, peer perlu melakukan polling untuk pesan sinyal jika terjadi perubahan atau penghentian sesi oleh peer lain. Contoh aplikasi WebRTC Book menggunakan opsi ini dengan beberapa pengoptimalan untuk frekuensi polling.
Sinyal skala
Meskipun layanan sinyal menggunakan bandwidth dan CPU yang relatif sedikit per klien, server sinyal untuk aplikasi populer mungkin harus menangani banyak pesan dari berbagai lokasi dengan tingkat serentak yang tinggi. Aplikasi WebRTC yang mendapatkan banyak traffic memerlukan server sinyal yang dapat menangani beban yang cukup besar. Anda tidak perlu membahasnya secara mendetail di sini, tetapi ada sejumlah opsi untuk pesan bervolume tinggi dan berperforma tinggi, termasuk yang berikut ini:
eXtensible Messaging and Presence Protocol (XMPP), yang awalnya dikenal sebagai Jabber-protokol yang dikembangkan untuk pesan instan yang dapat digunakan untuk sinyal (Implementasi server mencakup ejabberd dan Openfire. Klien JavaScript, seperti Strophe.js, menggunakan BOSH untuk mengemulasi streaming dua arah, tetapi karena berbagai alasan, BOSH mungkin tidak seefisien WebSocket dan, karena alasan yang sama, mungkin tidak dapat diskalakan dengan baik.) (Secara tidak langsung, Jingle adalah ekstensi XMPP untuk mengaktifkan suara dan video. Project WebRTC menggunakan komponen jaringan dan transpor dari library libjingle - implementasi Jingle dalam C++).
Library open source, seperti ZeroMQ (seperti yang digunakan oleh TokBox untuk layanan Rumour) dan OpenMQ (NullMQ menerapkan konsep ZeroMQ ke platform web menggunakan protokol STOMP melalui WebSocket.)
Platform pesan cloud komersial yang menggunakan WebSocket (meskipun dapat kembali ke long polling), seperti Pusher, Kaazing, dan PubNub (PubNub juga memiliki API untuk WebRTC.)
Platform WebRTC komersial, seperti vLine
(Panduan Teknologi Web Real-Time dari developer Phil Leggetter memberikan daftar lengkap layanan dan library pesan.)
Mem-build layanan sinyal dengan Socket.io di Node
Berikut adalah kode untuk aplikasi web sederhana yang menggunakan layanan sinyal yang dibuat dengan Socket.io di Node. Desain Socket.io memudahkan pembuatan layanan untuk bertukar pesan dan Socket.io sangat cocok untuk sinyal WebRTC karena konsep ruang bawaannya. Contoh ini tidak dirancang untuk diskalakan sebagai layanan sinyal tingkat produksi, tetapi mudah dipahami untuk sejumlah kecil pengguna.
Socket.io menggunakan WebSocket dengan penggantian: polling panjang AJAX, streaming multipart AJAX, Forever Iframe, dan polling JSONP. Node.js telah di-port ke berbagai backend, tetapi mungkin paling dikenal karena versi Node-nya yang digunakan dalam contoh ini.
Tidak ada WebRTC dalam contoh ini. Aplikasi ini hanya dirancang untuk menunjukkan cara membuat sinyal ke dalam aplikasi web. Lihat log konsol untuk melihat apa yang terjadi saat klien bergabung ke ruang dan bertukar pesan. Codelab WebRTC ini memberikan petunjuk langkah demi langkah tentang cara mengintegrasikannya ke dalam aplikasi chat video WebRTC yang lengkap.
Berikut adalah index.html
klien:
<!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>
Berikut adalah file JavaScript main.js
yang dirujuk di klien:
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);
});
Berikut adalah aplikasi server yang lengkap:
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);
});
});
(Anda tidak perlu mempelajari node-static untuk ini. Hanya kebetulan digunakan dalam contoh ini.)
Untuk menjalankan aplikasi ini di localhost, Anda harus menginstal Node, Socket.IO, dan node-static. Node dapat didownload dari Node.js (penginstalannya mudah dan cepat). Untuk menginstal Socket.IO dan node-static, jalankan Node Package Manager dari terminal di direktori aplikasi Anda:
npm install socket.io
npm install node-static
Untuk memulai server, jalankan perintah berikut dari terminal di direktori aplikasi Anda:
node server.js
Dari browser, buka localhost:2013
. Buka tab atau jendela baru di browser mana pun, lalu buka localhost:2013
lagi. Untuk melihat apa yang terjadi, periksa konsol. Di Chrome dan Opera, Anda dapat mengakses konsol melalui Google Chrome Developer Tools dengan Ctrl+Shift+J
(atau Command+Option+J
di Mac).
Apa pun pendekatan yang Anda pilih untuk sinyal, aplikasi backend dan klien Anda - setidaknya - harus menyediakan layanan yang mirip dengan contoh ini.
Gotcha sinyal
RTCPeerConnection
tidak akan mulai mengumpulkan kandidat hinggasetLocalDescription()
dipanggil. Hal ini diwajibkan dalam draf IETF JSEP.- Manfaatkan Trickle ICE. Panggil
addIceCandidate()
segera setelah kandidat tiba.
Server sinyal siap pakai
Jika Anda tidak ingin membuat server sendiri, ada beberapa server sinyal WebRTC yang tersedia, yang menggunakan Socket.IO seperti contoh sebelumnya dan terintegrasi dengan library JavaScript klien WebRTC:
- webRTC.io adalah salah satu library abstraksi pertama untuk WebRTC.
- Signalmaster adalah server sinyal yang dibuat untuk digunakan dengan library klien JavaScript SimpleWebRTC.
Jika Anda tidak ingin menulis kode sama sekali, platform WebRTC komersial lengkap tersedia dari perusahaan, seperti vLine, OpenTok, dan Asterisk.
Sebagai catatan, Ericsson membuat server sinyal menggunakan PHP di Apache pada awal WebRTC. Sekarang ini sudah tidak digunakan lagi, tetapi sebaiknya lihat kodenya jika Anda mempertimbangkan sesuatu yang serupa.
Keamanan sinyal
"Keamanan adalah seni untuk membuat tidak ada yang terjadi".
Salman Rushdie
Enkripsi wajib untuk semua komponen WebRTC.
Namun, mekanisme sinyal tidak ditentukan oleh standar WebRTC, jadi Anda dapat membuat sinyal aman. Jika penyerang berhasil membajak sinyal, mereka dapat menghentikan sesi, mengalihkan koneksi, serta merekam, mengubah, atau memasukkan konten.
Faktor terpenting dalam mengamankan sinyal adalah menggunakan protokol aman - HTTPS dan WSS (misalnya, TLS) - yang memastikan pesan tidak dapat disadap tanpa dienkripsi. Selain itu, berhati-hatilah agar tidak menyiarkan pesan sinyal dengan cara yang dapat diakses oleh pemanggil lain yang menggunakan server sinyal yang sama.
Setelah sinyal: Menggunakan ICE untuk mengatasi NAT dan firewall
Untuk sinyal metadata, aplikasi WebRTC menggunakan server perantara, tetapi untuk streaming media dan data yang sebenarnya setelah sesi dibuat, RTCPeerConnection
akan mencoba menghubungkan klien secara langsung atau peer-to-peer.
Dalam dunia yang lebih sederhana, setiap endpoint WebRTC akan memiliki alamat unik yang dapat ditukar dengan peer lain untuk berkomunikasi secara langsung.
Pada kenyataannya, sebagian besar perangkat berada di balik satu atau beberapa lapisan NAT, beberapa memiliki software antivirus yang memblokir port dan protokol tertentu, dan banyak yang berada di balik proxy dan firewall perusahaan. Firewall dan NAT sebenarnya dapat diterapkan oleh perangkat yang sama, seperti router WIFI rumah.
Aplikasi WebRTC dapat menggunakan framework ICE untuk mengatasi kompleksitas jaringan di dunia nyata. Agar hal ini dapat terjadi, aplikasi Anda harus meneruskan URL server ICE ke RTCPeerConnection
, seperti yang dijelaskan dalam artikel ini.
ICE mencoba menemukan jalur terbaik untuk menghubungkan peer. Algoritma ini mencoba semua kemungkinan secara paralel dan memilih opsi yang paling efisien yang berfungsi. ICE pertama-tama mencoba membuat koneksi menggunakan alamat host yang diperoleh dari sistem operasi dan kartu jaringan perangkat. Jika gagal (yang akan terjadi untuk perangkat di balik NAT), ICE akan mendapatkan alamat eksternal menggunakan server STUN dan, jika gagal, traffic akan dirutekan melalui server relay TURN.
Dengan kata lain, server STUN digunakan untuk mendapatkan alamat jaringan eksternal dan server TURN digunakan untuk meneruskan traffic jika koneksi langsung (peer-to-peer) gagal.
Setiap server TURN mendukung STUN. Server TURN adalah server STUN dengan fungsi relay bawaan tambahan. ICE juga mengatasi kompleksitas penyiapan NAT. Pada kenyataannya, hole-punching NAT mungkin memerlukan lebih dari sekadar alamat IP:port publik.
URL untuk server STUN dan/atau TURN (opsional) ditentukan oleh aplikasi WebRTC dalam objek konfigurasi iceServers
yang merupakan argumen pertama ke konstruktor RTCPeerConnection
. Untuk appr.tc, nilainya akan terlihat seperti ini:
{
'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'
}
]
}
Setelah RTCPeerConnection
memiliki informasi tersebut, keajaiban ICE akan terjadi secara otomatis. RTCPeerConnection
menggunakan framework ICE untuk mencari jalur terbaik di antara peer, yang bekerja dengan server STUN dan TURN sesuai kebutuhan.
STUN
NAT menyediakan alamat IP untuk perangkat agar dapat digunakan dalam jaringan lokal pribadi, tetapi alamat ini tidak dapat digunakan secara eksternal. Tanpa alamat publik, rekan WebRTC tidak dapat berkomunikasi. Untuk mengatasi masalah ini, WebRTC menggunakan STUN.
Server STUN berada di internet publik dan memiliki satu tugas sederhana - memeriksa alamat IP:port dari permintaan yang masuk (dari aplikasi yang berjalan di balik NAT) dan mengirim kembali alamat tersebut sebagai respons. Dengan kata lain, aplikasi menggunakan server STUN untuk menemukan IP:port-nya dari perspektif publik. Proses ini memungkinkan peer WebRTC mendapatkan alamat yang dapat diakses secara publik untuk dirinya sendiri, lalu meneruskannya ke peer lain melalui mekanisme sinyal untuk menyiapkan link langsung. (Dalam praktiknya, NAT yang berbeda bekerja dengan cara yang berbeda dan mungkin ada beberapa lapisan NAT, tetapi prinsipnya tetap sama.)
Server STUN tidak perlu melakukan banyak hal atau mengingat banyak hal, sehingga server STUN dengan spesifikasi yang relatif rendah dapat menangani banyak permintaan.
Sebagian besar panggilan WebRTC berhasil membuat koneksi menggunakan STUN - 86% menurut Webrtcstats.com, meskipun hal ini dapat lebih sedikit untuk panggilan antar-peer di balik firewall dan konfigurasi NAT yang kompleks.
TURN
RTCPeerConnection
mencoba menyiapkan komunikasi langsung antar-peer melalui UDP. Jika gagal, RTCPeerConnection
akan beralih ke TCP. Jika gagal, server TURN dapat digunakan sebagai penggantian, yang meneruskan data antar-endpoint.
Sebagai pengingat, TURN digunakan untuk meneruskan streaming audio, video, dan data antar-peer, bukan data sinyal.
Server TURN memiliki alamat publik, sehingga dapat dihubungi oleh peer meskipun peer berada di balik firewall atau proxy. Server TURN memiliki tugas yang secara konseptual sederhana - untuk meneruskan streaming. Namun, tidak seperti server STUN, server ini secara inheren menggunakan banyak bandwidth. Dengan kata lain, server TURN harus lebih andal.
Diagram ini menunjukkan cara kerja TURN. STUN murni tidak berhasil, sehingga setiap peer menggunakan server TURN.
Men-deploy server STUN dan TURN
Untuk pengujian, Google menjalankan server STUN publik, stun.l.google.com:19302, seperti yang digunakan oleh appr.tc. Untuk layanan STUN/TURN produksi, gunakan rfc5766-turn-server. Kode sumber untuk server STUN dan TURN tersedia di GitHub, tempat Anda juga dapat menemukan link ke beberapa sumber informasi tentang penginstalan server. Image VM untuk Amazon Web Services juga tersedia.
Server TURN alternatif di-rebuild, tersedia sebagai kode sumber dan juga untuk AWS. Berikut adalah petunjuk cara menyiapkan pengembalian dana di Compute Engine.
- Buka firewall sesuai kebutuhan untuk tcp=443, udp/tcp=3478.
- Buat empat instance, satu untuk setiap IP publik, image Ubuntu 12.06 Standar.
- Siapkan konfigurasi firewall lokal (izinkan SEMUA dari SEMUA).
- Alat penginstalan:
shell sudo apt-get install make sudo apt-get install gcc
- Instal libre dari creytiv.com/re.html.
- Ambil restund dari creytiv.com/restund.html dan ekstrak./
wget
hancke.name/restund-auth.patch dan terapkan denganpatch -p1 < restund-auth.patch
.- Jalankan
make
,sudo make install
untuk libre dan restund. - Sesuaikan
restund.conf
dengan kebutuhan Anda (ganti alamat IP dan pastikanrestund.conf
berisi secret bersama yang sama) lalu salin ke/etc
. - Salin
restund/etc/restund
ke/etc/init.d/
. - Konfigurasi pengembalian dana:
- Setel
LD_LIBRARY_PATH
. - Salin
restund.conf
ke/etc/restund.conf
. - Tetapkan
restund.conf
untuk menggunakan 10 yang tepat. Alamat IP.
- Setel
- Menjalankan pengembalian dana
- Menguji menggunakan klien stund dari mesin jarak jauh:
./client IP:port
Lebih dari satu lawan satu: WebRTC multipihak
Anda juga dapat melihat standar IETF yang diusulkan oleh Justin Uberti untuk REST API untuk akses ke Layanan TURN.
Kasus penggunaan untuk streaming media yang lebih dari sekadar panggilan satu lawan satu mudah dibayangkan. Misalnya, konferensi video antara sekelompok rekan kerja atau acara publik dengan satu pembicara dan ratusan atau jutaan penonton.
Aplikasi WebRTC dapat menggunakan beberapa RTCPeerConnections sehingga setiap endpoint terhubung ke setiap endpoint lainnya dalam konfigurasi mesh. Ini adalah pendekatan yang dilakukan oleh aplikasi, seperti talky.io, dan berfungsi dengan sangat baik untuk segelintir peer. Selain itu, pemrosesan dan konsumsi bandwidth menjadi berlebihan, terutama untuk klien seluler.
Atau, aplikasi WebRTC dapat memilih satu endpoint untuk mendistribusikan streaming ke semua endpoint lainnya dalam konfigurasi bintang. Anda juga dapat menjalankan endpoint WebRTC di server dan membuat mekanisme redistribusi Anda sendiri (contoh aplikasi klien disediakan oleh webrtc.org).
Mulai Chrome 31 dan Opera 18, MediaStream
dari satu RTCPeerConnection
dapat digunakan sebagai input untuk RTCPeerConnection
lainnya. Hal ini dapat memungkinkan arsitektur yang lebih fleksibel karena memungkinkan aplikasi web menangani pemilihan rute panggilan dengan memilih peer lain yang akan dihubungkan. Untuk melihat cara kerjanya, lihat Contoh WebRTC Relay koneksi peer dan Contoh WebRTC Beberapa koneksi peer.
Unit Kontrol Multipoint
Opsi yang lebih baik untuk sejumlah besar endpoint adalah menggunakan Multipoint Control Unit (MCU). Ini adalah server yang berfungsi sebagai jembatan untuk mendistribusikan media di antara sejumlah besar peserta. MCU dapat menangani resolusi, codec, dan kecepatan frame yang berbeda dalam konferensi video; menangani transcoding; melakukan penerusan streaming selektif; serta memadukan atau merekam audio dan video. Untuk panggilan multipihak, ada sejumlah masalah yang perlu dipertimbangkan, terutama cara menampilkan beberapa input video dan memadukan audio dari beberapa sumber. Platform cloud, seperti vLine, juga mencoba mengoptimalkan pemilihan rute traffic.
Anda dapat membeli paket hardware MCU lengkap atau membuat sendiri.
Beberapa opsi software MCU open source tersedia. Misalnya, Licode (sebelumnya dikenal sebagai Lynckia) memproduksi MCU open source untuk WebRTC. OpenTok memiliki Mantis.
Selain browser: VoIP, telepon, dan pesan
Sifat standar WebRTC memungkinkan komunikasi antara aplikasi WebRTC yang berjalan di browser dan perangkat atau platform yang berjalan di platform komunikasi lain, seperti telepon atau sistem konferensi video.
SIP adalah protokol sinyal yang digunakan oleh sistem VoIP dan konferensi video. Untuk mengaktifkan komunikasi antara aplikasi web WebRTC dan klien SIP, seperti sistem konferensi video, WebRTC memerlukan server proxy untuk memediasi sinyal. Sinyal harus mengalir melalui gateway, tetapi setelah komunikasi terjalin, traffic SRTP (video dan audio) dapat mengalir langsung secara peer to peer.
Public Switched Telephone Network (PSTN) adalah jaringan sirkuit-switched dari semua telepon analog "biasa". Untuk panggilan antara aplikasi web WebRTC dan telepon, traffic harus melalui gateway PSTN. Demikian pula, aplikasi web WebRTC memerlukan server XMPP perantara untuk berkomunikasi dengan endpoint Jingle seperti klien IM. Jingle dikembangkan oleh Google sebagai ekstensi untuk XMPP guna mengaktifkan suara dan video untuk layanan pesan. Implementasi WebRTC saat ini didasarkan pada library libjingle C++, implementasi Jingle yang awalnya dikembangkan untuk Talk.
Sejumlah aplikasi, library, dan platform memanfaatkan kemampuan WebRTC untuk berkomunikasi dengan dunia luar:
- sipML5: klien SIP JavaScript open source
- jsSIP: Library SIP JavaScript
- Phono: API ponsel JavaScript open source yang dibuat sebagai plugin
- Zingaya: widget ponsel yang dapat disematkan
- Twilio: suara dan pesan
- Uberconference: konferensi
Developer sipML5 juga telah membuat gateway webrtc2sip. Tethr dan Tropo telah menunjukkan framework untuk komunikasi bencana "dalam tas kerja" menggunakan sel OpenBTS untuk memungkinkan komunikasi antara ponsel fitur dan komputer melalui WebRTC. Itulah komunikasi telepon tanpa operator.
Cari tahu selengkapnya
Codelab WebRTC memberikan petunjuk langkah demi langkah tentang cara mem-build aplikasi chat video dan teks menggunakan layanan sinyal Socket.io yang berjalan di Node.
Presentasi WebRTC Google I/O dari tahun 2013 dengan WebRTC tech lead, Justin Uberti
Presentasi SFHTML5 Chris Wilson - Pengantar Aplikasi WebRTC
Buku setebal 350 halaman WebRTC: API dan Protokol RTCWEB dari Web Real-Time HTML5 memberikan banyak detail tentang jalur data dan sinyal, serta menyertakan sejumlah diagram topologi jaringan yang mendetail.
WebRTC dan Sinyal: Apa yang Kita Pelajari Selama Dua Tahun - Postingan blog TokBox tentang alasan tidak menyertakan sinyal dalam spesifikasi adalah ide yang bagus
A Practical Guide to Building WebRTC Apps Ben Strong memberikan banyak informasi tentang infrastruktur dan topologi WebRTC.
Bab WebRTC dalam High Performance Browser Networking Ilya Grigorik membahas arsitektur, kasus penggunaan, dan performa WebRTC secara mendalam.