Mulai menggunakan WebRTC

WebRTC adalah medan perang baru dalam perang panjang untuk web yang terbuka dan tidak terbebani.

Brendan Eich, penemu JavaScript

Komunikasi real-time tanpa plugin

Bayangkan dunia di mana ponsel, TV, dan komputer Anda dapat berkomunikasi di platform yang sama. Bayangkan betapa mudahnya menambahkan chat video dan berbagi data peer-to-peer ke aplikasi web Anda. Itulah visi WebRTC.

Ingin mencobanya? WebRTC tersedia di desktop dan perangkat seluler di Google Chrome, Safari, Firefox, dan Opera. Tempat yang baik untuk memulai adalah aplikasi chat video sederhana di appr.tc:

  1. Buka appr.tc di browser Anda.
  2. Klik Gabung untuk bergabung ke ruang chat dan izinkan aplikasi menggunakan webcam Anda.
  3. Buka URL yang ditampilkan di akhir halaman di tab baru atau, lebih baik lagi, di komputer lain.

Mulai cepat

Tidak punya waktu untuk membaca artikel ini atau hanya ingin kode?

Atau, langsung buka codelab WebRTC, panduan langkah demi langkah yang menjelaskan cara membuat aplikasi chat video lengkap, termasuk server pensinyalan sederhana.

Sejarah singkat WebRTC

Salah satu tantangan besar terakhir untuk web adalah memungkinkan komunikasi manusia melalui suara dan video: komunikasi real-time atau RTC. RTC harus senatural memasukkan teks di input teks dalam aplikasi web. Tanpa data tersebut, Anda akan terbatas dalam kemampuan untuk berinovasi dan mengembangkan cara baru bagi orang-orang untuk berinteraksi.

Secara historis, RTC bersifat korporat dan kompleks, sehingga memerlukan teknologi audio dan video mahal yang dilisensikan atau dikembangkan secara internal. Mengintegrasikan teknologi RTC dengan konten, data, dan layanan yang ada menjadi sulit dan memakan waktu, terutama di web.

Video chat Gmail menjadi populer pada tahun 2008 dan pada tahun 2011, Google memperkenalkan Hangouts, yang menggunakan Talk (seperti Gmail). Google membeli GIPS, sebuah perusahaan yang mengembangkan banyak komponen yang diperlukan untuk RTC, seperti codec dan teknik pembatalan gema. Google menyediakan teknologi yang dikembangkan oleh GIPS sebagai open source dan berinteraksi dengan badan standar yang relevan di Internet Engineering Task Force (IETF) dan World Wide Web Consortium (W3C) untuk memastikan konsensus industri. Pada Mei 2011, Ericsson membuat implementasi WebRTC pertama.

WebRTC menerapkan standar terbuka untuk komunikasi video, audio, dan data real-time tanpa plugin. Kebutuhannya nyata:

  • Banyak layanan web yang menggunakan RTC, tetapi memerlukan download, aplikasi native, atau plugin. Aplikasi tersebut termasuk Skype, Facebook, dan Hangouts.
  • Mendownload, menginstal, dan mengupdate plugin itu rumit, rentan terhadap error, dan menjengkelkan.
  • Plugin sulit di-deploy, di-debug, dipecahkan masalahnya, diuji, dan dipelihara - serta mungkin memerlukan pemberian lisensi dan integrasi dengan teknologi yang kompleks dan mahal. Sering kali sulit untuk membujuk orang agar menginstal plugin sejak awal.

Prinsip panduan project WebRTC adalah bahwa API-nya harus open source, gratis, standar, terintegrasi ke dalam browser web, dan lebih efisien daripada teknologi yang ada.

Di mana kita sekarang?

WebRTC digunakan di berbagai aplikasi, seperti Google Meet. WebRTC juga telah diintegrasikan dengan aplikasi native WebKitGTK+ dan Qt.

WebRTC mengimplementasikan tiga API ini: - MediaStream (juga dikenal sebagai getUserMedia) - RTCPeerConnection - RTCDataChannel

API ditentukan dalam dua spesifikasi ini:

Ketiga API ini didukung di perangkat seluler dan desktop oleh Chrome, Safari, Firefox, Edge, dan Opera.

getUserMedia: Untuk demo dan kode, lihat contoh WebRTC atau coba contoh luar biasa Chris Wilson yang menggunakan getUserMedia sebagai input untuk audio web.

RTCPeerConnection: Untuk demo sederhana dan aplikasi video chat yang berfungsi penuh, lihat WebRTC samples Peer connection dan appr.tc. Aplikasi ini menggunakan adapter.js, shim JavaScript yang dikelola oleh Google dengan bantuan dari komunitas WebRTC, untuk mengabstraksi perbedaan browser dan perubahan spesifikasi.

RTCDataChannel: Untuk melihat cara kerjanya, lihat contoh WebRTC untuk melihat salah satu demo saluran data.

Codelab WebRTC menunjukkan cara menggunakan ketiga API untuk membangun aplikasi sederhana untuk berbagi file dan melakukan chat video.

WebRTC pertama Anda

Aplikasi WebRTC perlu melakukan beberapa hal:

  • Mendapatkan audio, video, atau data lain yang di-streaming.
  • Mendapatkan informasi jaringan, seperti alamat IP dan port, serta menukarkannya dengan klien WebRTC lain (dikenal sebagai peer) untuk mengaktifkan koneksi, bahkan melalui NAT dan firewall.
  • Mengoordinasikan komunikasi sinyal untuk melaporkan error dan memulai atau menutup sesi.
  • Bertukar informasi tentang kemampuan media dan klien, seperti resolusi dan codec.
  • Mengomunikasikan streaming audio, video, atau data.

Untuk mendapatkan dan mengomunikasikan data streaming, WebRTC menerapkan API berikut:

  • MediaStream mendapatkan akses ke aliran data, seperti dari kamera dan mikrofon pengguna.
  • RTCPeerConnection memungkinkan panggilan audio atau video dengan fasilitas untuk enkripsi dan pengelolaan bandwidth.
  • RTCDataChannel memungkinkan komunikasi peer-to-peer dari data generik.

(Pembahasan mendetail tentang aspek jaringan dan sinyal WebRTC akan dilakukan nanti.)

API MediaStream (juga dikenal sebagai API getUserMedia)

MediaStream API merepresentasikan aliran media yang disinkronkan. Misalnya, streaming yang diambil dari input kamera dan mikrofon memiliki trek video dan audio yang disinkronkan. (Jangan keliru mengira MediaStreamTrack sebagai elemen <track>, yang sama sekali berbeda.)

Mungkin cara termudah untuk memahami MediaStream API adalah dengan melihatnya di alam bebas:

  1. Di browser Anda, buka contoh WebRTC getUserMedia.
  2. Buka konsol.
  3. Periksa variabel stream, yang berada dalam cakupan global.

Setiap MediaStream memiliki input, yang mungkin berupa MediaStream yang dihasilkan oleh getUserMedia(), dan output, yang mungkin diteruskan ke elemen video atau RTCPeerConnection.

Metode getUserMedia() mengambil parameter objek MediaStreamConstraints dan menampilkan Promise yang diselesaikan ke objek MediaStream.

Setiap MediaStream memiliki label, seperti 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'. Array MediaStreamTrack ditampilkan oleh metode getAudioTracks() dan getVideoTracks().

Untuk contoh getUserMedia, stream.getAudioTracks() menampilkan array kosong (karena tidak ada audio) dan, dengan asumsi webcam yang berfungsi terhubung, stream.getVideoTracks() menampilkan array dari satu MediaStreamTrack yang merepresentasikan streaming dari webcam. Setiap MediaStreamTrack memiliki jenis ('video' atau 'audio'), label (seperti 'FaceTime HD Camera (Built-in)'), dan merepresentasikan satu atau beberapa channel audio atau video. Dalam hal ini, hanya ada satu trek video dan tidak ada audio, tetapi mudah untuk membayangkan kasus penggunaan yang lebih banyak, seperti aplikasi chat yang mendapatkan streaming dari kamera depan, kamera belakang, mikrofon, dan aplikasi yang membagikan layarnya.

MediaStream dapat dilampirkan ke elemen video dengan menyetel atribut srcObject. Sebelumnya, hal ini dilakukan dengan menyetel atribut src ke URL objek yang dibuat dengan URL.createObjectURL(), tetapi hal ini tidak digunakan lagi.

getUserMedia juga dapat digunakan sebagai node input untuk Web Audio API:

// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
  audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
  audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
  console.log('Sorry! Web Audio not supported.');
}

// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;

// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;

navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
  // Create an AudioNode from the stream.
  const mediaStreamSource =
    audioContext.createMediaStreamSource(stream);
  mediaStreamSource.connect(filterNode);
  filterNode.connect(gainNode);
  // Connect the gain node to the destination. For example, play the sound.
  gainNode.connect(audioContext.destination);
});

Aplikasi dan ekstensi berbasis Chromium juga dapat menggabungkan getUserMedia. Menambahkan izin audioCapture dan/atau videoCapture ke manifes memungkinkan izin diminta dan diberikan hanya sekali saat penginstalan. Setelah itu, pengguna tidak akan dimintai izin untuk akses kamera atau mikrofon.

Izin hanya perlu diberikan satu kali untuk getUserMedia(). Saat pertama kali, tombol Izinkan ditampilkan di infobar browser. Akses HTTP untuk getUserMedia() dihentikan oleh Chrome pada akhir tahun 2015 karena diklasifikasikan sebagai Fitur canggih.

Tujuannya mungkin untuk mengaktifkan MediaStream untuk semua sumber data streaming, bukan hanya kamera atau mikrofon. Hal ini akan memungkinkan streaming dari data tersimpan atau sumber data arbitrer, seperti sensor atau input lainnya.

getUserMedia() benar-benar menjadi hidup jika dikombinasikan dengan API dan library JavaScript lainnya:

  • Webcam Toy adalah aplikasi booth foto yang menggunakan WebGL untuk menambahkan efek aneh dan luar biasa ke foto yang dapat dibagikan atau disimpan secara lokal.
  • FaceKat adalah game pelacakan wajah yang dibuat dengan headtrackr.js.
  • ASCII Camera menggunakan Canvas API untuk membuat gambar ASCII.
Gambar ASCII yang dihasilkan oleh idevelop.ro/ascii-camera
Seni ASCII gUM!

Batasan

Batasan dapat digunakan untuk menetapkan nilai resolusi video untuk getUserMedia(). Hal ini juga memungkinkan dukungan untuk batasan lainnya, seperti rasio aspek; mode menghadap (kamera depan atau belakang); kecepatan frame, tinggi dan lebar; serta metode applyConstraints().

Sebagai contoh, lihat Contoh WebRTC getUserMedia: pilih resolusi.

Menetapkan nilai batasan yang tidak diizinkan akan memberikan DOMException atau OverconstrainedError jika, misalnya, resolusi yang diminta tidak tersedia. Untuk melihat cara kerjanya, lihat Contoh WebRTC getUserMedia: pilih resolusi untuk melihat demo.

Perekaman layar dan tab

Aplikasi Chrome juga memungkinkan untuk membagikan video live dari satu tab browser atau seluruh desktop melalui API chrome.tabCapture dan chrome.desktopCapture. (Untuk melihat demo dan informasi selengkapnya, lihat Berbagi layar dengan WebRTC. Artikel ini sudah beberapa tahun, tetapi masih menarik.)

Anda juga dapat menggunakan perekaman layar sebagai sumber MediaStream di Chrome menggunakan batasan chromeMediaSource eksperimental. Perhatikan bahwa pengambilan screenshot memerlukan HTTPS dan hanya boleh digunakan untuk pengembangan karena diaktifkan melalui tanda command line seperti yang dijelaskan dalam postingan ini.

Pensinyalan: Kontrol sesi, jaringan, dan informasi media

WebRTC menggunakan RTCPeerConnection untuk mengomunikasikan data streaming antar-browser (juga dikenal sebagai peer), tetapi juga memerlukan mekanisme untuk mengoordinasikan komunikasi dan mengirim pesan kontrol, sebuah proses yang dikenal sebagai pensinyalan. Metode dan protokol pensinyalan tidak ditentukan oleh WebRTC. Pensinyalan bukan bagian dari RTCPeerConnection API.

Sebagai gantinya, developer aplikasi WebRTC dapat memilih protokol pesan apa pun yang mereka inginkan, seperti SIP atau XMPP, dan saluran komunikasi dupleks (dua arah) yang sesuai. Contoh appr.tc menggunakan XHR dan Channel API sebagai mekanisme pensinyalan. codelab ini menggunakan Socket.io yang berjalan di server Node.

Pensinyalan digunakan untuk menukar tiga jenis informasi:

  • Pesan kontrol sesi: untuk memulai atau menutup komunikasi dan melaporkan error.
  • Konfigurasi jaringan: bagi dunia luar, apa alamat IP dan port komputer Anda?
  • Kemampuan media: codec dan resolusi apa yang dapat ditangani oleh browser Anda dan browser yang ingin berkomunikasi dengannya?

Pertukaran informasi melalui pensinyalan harus berhasil diselesaikan sebelum streaming peer-to-peer dapat dimulai.

Misalnya, bayangkan Alice ingin berkomunikasi dengan Bob. Berikut contoh kode dari spesifikasi WebRTC W3C, yang menunjukkan proses pensinyalan yang sedang berlangsung. Kode mengasumsikan keberadaan beberapa mekanisme sinyal yang dibuat dalam metode createSignalingChannel(). Perhatikan juga bahwa di Chrome dan Opera, RTCPeerConnection saat ini memiliki awalan.

// 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);
  }
};

// Once 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);
  }
};

Pertama, Alice dan Bob bertukar informasi jaringan. (Ekspresi menemukan kandidat mengacu pada proses menemukan antarmuka dan port jaringan menggunakan framework ICE.)

  1. Alice membuat objek RTCPeerConnection dengan handler onicecandidate, yang berjalan saat kandidat jaringan tersedia.
  2. Alice mengirim data kandidat yang diserialisasi ke Bob melalui saluran sinyal apa pun yang mereka gunakan, seperti WebSocket atau mekanisme lainnya.
  3. Saat Bob menerima pesan kandidat dari Alice, dia memanggil addIceCandidate untuk menambahkan kandidat ke deskripsi peer jarak jauh.

Klien WebRTC (juga dikenal sebagai peer, atau Alice dan Bob dalam contoh ini) juga perlu memastikan dan menukar informasi media audio dan video lokal dan jarak jauh, seperti resolusi dan kemampuan codec. Sinyal untuk bertukar informasi konfigurasi media dilakukan dengan bertukar penawaran dan jawaban menggunakan Session Description Protocol (SDP):

  1. Alice menjalankan metode RTCPeerConnection createOffer(). Hasil dari ini diteruskan sebagai RTCSessionDescription - deskripsi sesi lokal Alice.
  2. Dalam callback, Alice menetapkan deskripsi lokal menggunakan setLocalDescription(), lalu mengirimkan deskripsi sesi ini ke Bob melalui saluran sinyal mereka. Perhatikan bahwa RTCPeerConnection tidak akan mulai mengumpulkan kandidat hingga setLocalDescription() dipanggil. Hal ini dikodifikasi dalam draf IETF JSEP.
  3. Bob menetapkan deskripsi yang dikirim Alice kepadanya sebagai deskripsi jarak jauh menggunakan setRemoteDescription().
  4. Bob menjalankan metode RTCPeerConnection createAnswer(), meneruskan deskripsi jarak jauh yang dia dapatkan dari Alice sehingga sesi lokal yang kompatibel dengan sesi Alice dapat dibuat. Callback createAnswer() meneruskan RTCSessionDescription. Bob menetapkannya sebagai deskripsi lokal dan mengirimkannya ke Alice.
  5. Saat Alice mendapatkan deskripsi sesi Bob, dia menetapkannya sebagai deskripsi jarak jauh dengan setRemoteDescription.
  6. Ping!

Objek RTCSessionDescription adalah blob yang sesuai dengan Session Description Protocol, SDP. Jika diserialisasi, objek SDP akan terlihat seperti ini:

v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126

// ...

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810

Akuisisi dan pertukaran informasi jaringan dan media dapat dilakukan secara bersamaan, tetapi kedua proses harus selesai sebelum streaming audio dan video antar-peer dapat dimulai.

Arsitektur penawaran/jawaban yang dijelaskan sebelumnya disebut JavaScript Session Establishment Protocol, atau JSEP. (Ada animasi yang sangat bagus yang menjelaskan proses pensinyalan dan streaming dalam video demo Ericsson untuk penerapan WebRTC pertamanya.)

Diagram arsitektur JSEP
Arsitektur JSEP

Setelah proses pemberian sinyal berhasil diselesaikan, data dapat di-streaming langsung peer-to-peer, antara pemanggil dan penerima panggilan - atau, jika gagal, melalui server relay perantara (selengkapnya nanti). Streaming adalah tugas RTCPeerConnection.

RTCPeerConnection

RTCPeerConnection adalah komponen WebRTC yang menangani komunikasi data streaming yang stabil dan efisien antar-peer.

Berikut adalah diagram arsitektur WebRTC yang menunjukkan peran RTCPeerConnection. Seperti yang akan Anda perhatikan, bagian hijau sangat rumit.

Diagram arsitektur WebRTC
Arsitektur WebRTC (dari webrtc.org)

Dari perspektif JavaScript, hal utama yang perlu dipahami dari diagram ini adalah bahwa RTCPeerConnection melindungi developer web dari berbagai kompleksitas yang tersembunyi di bawahnya. Codec dan protokol yang digunakan oleh WebRTC melakukan banyak pekerjaan untuk memungkinkan komunikasi real-time, bahkan melalui jaringan yang tidak andal:

  • Penyembunyian kehilangan paket
  • Peredam gema
  • Adaptasi bandwidth
  • Buffering jitter dinamis
  • Kontrol penguatan otomatis
  • Pengurangan dan peredaman bising
  • Pembersihan gambar

Kode W3C sebelumnya menunjukkan contoh sederhana WebRTC dari perspektif pensinyalan. Berikut adalah panduan untuk dua aplikasi WebRTC yang berfungsi. Yang pertama adalah contoh sederhana untuk mendemonstrasikan RTCPeerConnection dan yang kedua adalah klien chat video yang beroperasi sepenuhnya.

RTCPeerConnection tanpa server

Kode berikut diambil dari WebRTC samples Peer connection, yang memiliki lokal dan RTCPeerConnection jarak jauh (serta video lokal dan jarak jauh) di satu halaman web. Hal ini tidak terlalu berguna - pemanggil dan yang dipanggil berada di halaman yang sama - tetapi membuat cara kerja API RTCPeerConnection menjadi sedikit lebih jelas karena objek RTCPeerConnection di halaman dapat bertukar data dan pesan secara langsung tanpa harus menggunakan mekanisme sinyal perantara.

Dalam contoh ini, pc1 mewakili peer lokal (pemanggil) dan pc2 mewakili peer jarak jauh (penerima panggilan).

Penelepon

  1. Buat RTCPeerConnection baru dan tambahkan aliran dari getUserMedia(): ```js // Servers adalah file konfigurasi opsional. (Lihat pembahasan TURN dan STUN di bagian selanjutnya.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
  1. Buat penawaran dan tetapkan sebagai deskripsi lokal untuk pc1 dan sebagai deskripsi jarak jauh untuk pc2. Hal ini dapat dilakukan langsung dalam kode tanpa menggunakan pensinyalan karena pemanggil dan penerima panggilan berada di halaman yang sama: js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );

Callee

  1. Buat pc2 dan, saat streaming dari pc1 ditambahkan, tampilkan di elemen video: js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }

RTCPeerConnection API plus server

Di dunia nyata, WebRTC memerlukan server, meskipun sederhana, sehingga hal berikut dapat terjadi:

  • Pengguna saling menemukan dan bertukar detail dunia nyata, seperti nama.
  • Aplikasi klien WebRTC (peer) bertukar informasi jaringan.
  • Peer bertukar data tentang media, seperti format dan resolusi video.
  • Aplikasi klien WebRTC melintasi gateway NAT dan firewall.

Dengan kata lain, WebRTC memerlukan empat jenis fungsi sisi server:

  • Penemuan dan komunikasi pengguna
  • Pemberian isyarat
  • NAT/firewall traversal
  • Server relay jika komunikasi peer-to-peer gagal

NAT traversal, jaringan peer-to-peer, dan persyaratan untuk membangun aplikasi server untuk penemuan dan pensinyalan pengguna berada di luar cakupan artikel ini. Dapat dikatakan bahwa protokol STUN dan ekstensinya, TURN, digunakan oleh framework ICE untuk memungkinkan RTCPeerConnection mengatasi traversal NAT dan ketidakpastian jaringan lainnya.

ICE adalah framework untuk menghubungkan peer, seperti dua klien chat video. Awalnya, ICE mencoba menghubungkan peer secara langsung dengan latensi serendah mungkin melalui UDP. Dalam proses ini, server STUN memiliki satu tugas: memungkinkan peer di belakang NAT mengetahui alamat dan port publiknya. (Untuk mengetahui informasi selengkapnya tentang STUN dan TURN, lihat Membangun layanan backend yang diperlukan untuk aplikasi WebRTC.)

Menemukan kandidat koneksi
Menemukan kandidat koneksi

Jika UDP gagal, ICE akan mencoba TCP. Jika koneksi langsung gagal - khususnya karena traversal NAT dan firewall perusahaan - ICE menggunakan server TURN perantara (relay). Dengan kata lain, ICE pertama-tama menggunakan STUN dengan UDP untuk menghubungkan peer secara langsung dan, jika gagal, akan melakukan failover ke server relai TURN. Ekspresi menemukan kandidat mengacu pada proses menemukan antarmuka dan port jaringan.

Jalur data WebRTC
Jalur data WebRTC

Engineer WebRTC, Justin Uberti, memberikan informasi selengkapnya tentang ICE, STUN, dan TURN dalam presentasi WebRTC Google I/O 2013. (Slide presentasi memberikan contoh penerapan server TURN dan STUN.)

Klien video chat sederhana

Tempat yang baik untuk mencoba WebRTC, lengkap dengan signaling dan NAT/firewall traversal menggunakan server STUN, adalah demo video chat di appr.tc. Aplikasi ini menggunakan adapter.js, shim untuk mengisolasi aplikasi dari perubahan spesifikasi dan perbedaan awalan.

Kode sengaja dibuat verbose dalam logging-nya. Periksa konsol untuk memahami urutan peristiwa. Berikut adalah panduan mendetail tentang kode tersebut.

Topologi jaringan

WebRTC, sebagaimana diimplementasikan saat ini, hanya mendukung komunikasi satu-ke-satu, tetapi dapat digunakan dalam skenario jaringan yang lebih kompleks, seperti dengan beberapa peer yang masing-masing berkomunikasi satu sama lain secara langsung atau melalui Multipoint Control Unit (MCU), yaitu server yang dapat menangani sejumlah besar peserta dan melakukan penerusan stream selektif, serta mencampur atau merekam audio dan video.

Diagram topologi Multipoint Control Unit
Contoh topologi Multipoint Control Unit

Banyak aplikasi WebRTC yang ada hanya mendemonstrasikan komunikasi antara browser web, tetapi server gateway dapat memungkinkan aplikasi WebRTC yang berjalan di browser berinteraksi dengan perangkat, seperti telepon (juga dikenal sebagai PSTN) dan dengan sistem VOIP. Pada Mei 2012, Doubango Telecom merilis klien SIP sipml5 open source yang dibuat dengan WebRTC dan WebSocket, yang (di antara potensi penggunaan lainnya) memungkinkan panggilan video antara browser dan aplikasi yang berjalan di iOS dan Android. Di Google I/O, Tethr dan Tropo mendemonstrasikan framework untuk komunikasi saat bencana dalam koper menggunakan sel OpenBTS untuk mengaktifkan komunikasi antara ponsel biasa dan komputer melalui WebRTC. Komunikasi telepon tanpa operator.

Demo Tethr/Tropo di Google I/O 2012
Tethr/Tropo: Disaster communications in a briefcase

RTCDataChannel API<

Selain audio dan video, WebRTC mendukung komunikasi real-time untuk jenis data lainnya.

API RTCDataChannel memungkinkan pertukaran data arbitrer peer-to-peer dengan latensi rendah dan throughput tinggi. Untuk demo halaman tunggal dan mempelajari cara membuat aplikasi transfer file sederhana, lihat contoh WebRTC dan codelab WebRTC.

Ada banyak potensi kasus penggunaan untuk API, termasuk:

  • Game
  • Aplikasi desktop jarak jauh
  • Chat teks real-time
  • Transfer file
  • Jaringan terdesentralisasi

API ini memiliki beberapa fitur untuk mengoptimalkan RTCPeerConnection dan memungkinkan komunikasi peer-to-peer yang efektif dan fleksibel:

  • Pemanfaatan penyiapan sesi RTCPeerConnection
  • Beberapa saluran serentak dengan prioritas
  • Semantik pengiriman yang andal dan tidak andal
  • Keamanan bawaan (DTLS) dan kontrol kemacetan
  • Dapat digunakan dengan atau tanpa audio atau video

Sintaksisnya sengaja dibuat mirip dengan WebSocket dengan metode send() dan peristiwa message:

const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
  localConnection.createDataChannel('sendDataChannel');

// ...

remoteConnection.ondatachannel = (event) => {
  receiveChannel = event.channel;
  receiveChannel.onmessage = onReceiveMessage;
  receiveChannel.onopen = onReceiveChannelStateChange;
  receiveChannel.onclose = onReceiveChannelStateChange;
};

function onReceiveMessage(event) {
  document.querySelector("textarea#send").value = event.data;
}

document.querySelector("button#send").onclick = () => {
  var data = document.querySelector("textarea#send").value;
  sendChannel.send(data);
};

Komunikasi terjadi langsung antar-browser, sehingga RTCDataChannel bisa jauh lebih cepat daripada WebSocket meskipun server relay (TURN) diperlukan saat hole-punching untuk mengatasi kegagalan firewall dan NAT.

RTCDataChannel tersedia di Chrome, Safari, Firefox, Opera, dan Samsung Internet. Game Cube Slam menggunakan API untuk mengomunikasikan status game. Bermain dengan teman atau bermain dengan beruang! Platform inovatif Sharefest memungkinkan berbagi file melalui RTCDataChannel dan peerCDN menawarkan sekilas tentang cara WebRTC dapat memungkinkan distribusi konten peer-to-peer.

Untuk mengetahui informasi selengkapnya tentang RTCDataChannel, lihat spesifikasi protokol draf IETF.

Keamanan

Ada beberapa cara aplikasi atau plugin komunikasi real-time dapat membahayakan keamanan. Contoh:

  • Media atau data yang tidak dienkripsi dapat dicegat antara browser, atau antara browser dan server.
  • Aplikasi dapat merekam dan mendistribusikan video atau audio tanpa sepengetahuan pengguna.
  • Malware atau virus mungkin diinstal bersama dengan plugin atau aplikasi yang tampaknya tidak berbahaya.

WebRTC memiliki beberapa fitur untuk menghindari masalah ini:

  • Penerapan WebRTC menggunakan protokol yang aman, seperti DTLS dan SRTP.
  • Enkripsi wajib dilakukan untuk semua komponen WebRTC, termasuk mekanisme pensinyalan.
  • WebRTC bukan plugin. Komponennya berjalan di sandbox browser dan bukan dalam proses terpisah. Komponen tidak memerlukan penginstalan terpisah dan diupdate setiap kali browser diupdate.
  • Akses kamera dan mikrofon harus diberikan secara eksplisit dan, saat kamera atau mikrofon berjalan, hal ini ditampilkan dengan jelas oleh antarmuka pengguna.

Pembahasan lengkap tentang keamanan untuk media streaming tidak termasuk dalam cakupan artikel ini. Untuk mengetahui informasi selengkapnya, lihat Proposed WebRTC Security Architecture yang diusulkan oleh IETF.

Kesimpulan

API dan standar WebRTC dapat mendemokratisasi dan mendesentralisasi alat untuk pembuatan konten dan komunikasi, termasuk telepon, game, produksi video, pembuatan musik, dan pengumpulan berita.

Teknologi tidak akan lebih mengganggu daripada ini.

Seperti yang dikatakan blogger Phil Edholm, "WebRTC dan HTML5 berpotensi memungkinkan transformasi yang sama untuk komunikasi real-time seperti yang dilakukan browser asli untuk informasi."

Developer tools

Pelajari lebih lanjut

Standar dan protokol

Ringkasan dukungan WebRTC

API MediaStream dan getUserMedia

  • Chrome desktop 18.0.1008 dan yang lebih baru; Chrome untuk Android 29 dan yang lebih baru
  • Opera 18 dan yang lebih tinggi; Opera untuk Android 20 dan yang lebih tinggi
  • Opera 12, Opera Mobile 12 (berdasarkan mesin Presto)
  • Firefox 17 dan yang lebih baru
  • Microsoft Edge 16 dan yang lebih baru
  • Safari 11.2 dan yang lebih baru di iOS, serta 11.1 dan yang lebih baru di MacOS
  • UC 11.8 dan yang lebih baru di Android
  • Samsung Internet 4 dan yang lebih baru

RTCPeerConnection API

  • Chrome desktop 20 dan yang lebih tinggi; Chrome untuk Android 29 dan yang lebih tinggi (tanpa tanda)
  • Opera 18 dan yang lebih tinggi (aktif secara default); Opera untuk Android 20 dan yang lebih tinggi (aktif secara default)
  • Firefox 22 dan yang lebih baru (aktif secara default)
  • Microsoft Edge 16 dan yang lebih baru
  • Safari 11.2 dan yang lebih baru di iOS, serta 11.1 dan yang lebih baru di MacOS
  • Samsung Internet 4 dan yang lebih baru

RTCDataChannel API

  • Versi eksperimental di Chrome 25, tetapi lebih stabil (dan dengan interoperabilitas Firefox) di Chrome 26 dan yang lebih baru; Chrome untuk Android 29 dan yang lebih baru
  • Versi stabil (dan dengan interoperabilitas Firefox) di Opera 18 dan yang lebih tinggi; Opera untuk Android 20 dan yang lebih tinggi
  • Firefox 22 dan yang lebih baru (aktif secara default)

Untuk mengetahui informasi yang lebih mendetail tentang dukungan lintas platform untuk API, seperti getUserMedia dan RTCPeerConnection, lihat caniuse.com dan Status Platform Chrome.

API native untuk RTCPeerConnection juga tersedia di dokumentasi di webrtc.org.