Mulai menggunakan WebRTC

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

Brendan Eich, penemu JavaScript

Komunikasi real-time tanpa plugin

Bayangkan dunia tempat 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 tepat 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 mem-build aplikasi chat video lengkap, termasuk server sinyal sederhana.

Sejarah singkat WebRTC

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

Secara historis, RTC bersifat korporat dan kompleks, sehingga memerlukan teknologi audio dan video yang mahal untuk dilisensikan atau dikembangkan secara internal. Mengintegrasikan teknologi RTC dengan konten, data, dan layanan yang ada sangat 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, perusahaan yang mengembangkan banyak komponen yang diperlukan untuk RTC, seperti codec dan teknik peredam gema. Google merilis 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 menggunakan RTC, tetapi memerlukan download, aplikasi native, atau plugin. Aplikasi ini termasuk Skype, Facebook, dan Hangouts.
  • Mendownload, menginstal, dan mengupdate plugin adalah hal yang rumit, rentan error, dan menjengkelkan.
  • Plugin sulit di-deploy, di-debug, di-troubleshoot, diuji, dan dikelola - serta mungkin memerlukan pemberian lisensi dan integrasi dengan teknologi yang kompleks dan mahal. Sering kali sulit untuk meyakinkan orang agar menginstal plugin.

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

Di mana kita sekarang?

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

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

API ditentukan dalam dua spesifikasi ini:

Ketiga API tersebut 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 melihat demo sederhana dan aplikasi chat video yang berfungsi penuh, lihat Contoh WebRTC 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 mem-build aplikasi sederhana untuk chat video dan berbagi file.

WebRTC pertama Anda

Aplikasi WebRTC perlu melakukan beberapa hal:

  • Mendapatkan audio, video, atau data streaming lainnya.
  • Dapatkan informasi jaringan, seperti alamat IP dan port, lalu tukarkan dengan klien WebRTC lain (dikenal sebagai peer) untuk mengaktifkan koneksi, bahkan melalui NAT dan firewall.
  • Mengkoordinasikan komunikasi sinyal untuk melaporkan error dan memulai atau menutup sesi.
  • Bertukar informasi tentang media dan kemampuan klien, seperti resolusi dan codec.
  • Mengirimkan audio, video, atau data streaming.

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 data generik.

(Akan ada diskusi mendetail tentang aspek jaringan dan sinyal WebRTC nanti.)

MediaStream API (juga dikenal sebagai getUserMedia API)

MediaStream API mewakili streaming media yang disinkronkan. Misalnya, streaming yang diambil dari input kamera dan mikrofon memiliki trek video dan audio yang disinkronkan. (Jangan bingungkan MediaStreamTrack dengan elemen <track>, yang merupakan sesuatu yang sepenuhnya berbeda.)

Mungkin cara termudah untuk memahami MediaStream API adalah dengan melihatnya di dunia nyata:

  1. Di browser, 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() menggunakan parameter objek MediaStreamConstraints dan menampilkan Promise yang di-resolve 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 mewakili streaming dari webcam. Setiap MediaStreamTrack memiliki jenis ('video' atau 'audio'), label (seperti 'FaceTime HD Camera (Built-in)'), dan mewakili satu atau beberapa saluran audio atau video. Dalam hal ini, hanya ada satu trek video dan tidak ada audio, tetapi mudah untuk membayangkan kasus penggunaan yang memiliki 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 menetapkan atribut srcObject. Sebelumnya, hal ini dilakukan dengan menetapkan atribut src ke URL objek yang dibuat dengan URL.createObjectURL(), tetapi cara 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 menyertakan getUserMedia. Menambahkan izin audioCapture dan/atau videoCapture ke manifes memungkinkan izin diminta dan diberikan hanya sekali setelah 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 akan ditampilkan di infobar browser. Akses HTTP untuk getUserMedia() tidak digunakan lagi oleh Chrome pada akhir tahun 2015 karena diklasifikasikan sebagai Fitur canggih.

Tujuannya adalah untuk mengaktifkan MediaStream untuk sumber data streaming apa pun, bukan hanya kamera atau mikrofon. Hal ini akan memungkinkan streaming dari data yang disimpan atau sumber data arbitrer, seperti sensor atau input lainnya.

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

  • Webcam Toy adalah aplikasi photobooth yang menggunakan WebGL untuk menambahkan efek aneh dan menakjubkan 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
Gambar 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: memilih 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: memilih resolusi untuk melihat demo.

Tangkapan layar dan tab

Aplikasi Chrome juga memungkinkan Anda berbagi 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 rekaman 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 flag command line seperti yang dijelaskan dalam postingan ini.

Sinyal: Informasi kontrol sesi, jaringan, dan 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 sinyal. Metode dan protokol sinyal tidak ditentukan oleh WebRTC. Sinyal 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 duplex (dua arah) yang sesuai. Contoh appr.tc menggunakan XHR dan Channel API sebagai mekanisme sinyal. Codelab ini menggunakan Socket.io yang berjalan di server Node.

Sinyal digunakan untuk bertukar tiga jenis informasi:

  • Pesan kontrol sesi: untuk melakukan inisialisasi atau menutup komunikasi dan melaporkan error.
  • Konfigurasi jaringan: untuk 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 diajak berkomunikasi?

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

Misalnya, bayangkan Alice ingin berkomunikasi dengan Bob. Berikut adalah contoh kode dari spesifikasi WebRTC W3C, yang menunjukkan proses sinyal yang sedang berjalan. Kode ini mengasumsikan adanya 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 pengendali 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 mendapatkan pesan kandidat dari Alice, ia 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 bertukar informasi media audio dan video lokal dan jarak jauh, seperti kemampuan resolusi dan codec. Sinyal untuk bertukar informasi konfigurasi media dilanjutkan dengan bertukar penawaran dan jawaban menggunakan Session Description Protocol (SDP):

  1. Alice menjalankan metode RTCPeerConnection createOffer(). Hasil dari ini diteruskan RTCSessionDescription - deskripsi sesi lokal Alice.
  2. Dalam callback, Alice menetapkan deskripsi lokal menggunakan setLocalDescription(), lalu mengirim 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 dikirimkan Alice kepadanya sebagai deskripsi jarak jauh menggunakan setRemoteDescription().
  4. Bob menjalankan metode RTCPeerConnection createAnswer(), yang meneruskan deskripsi jarak jauh yang dia dapatkan dari Alice sehingga sesi lokal dapat dibuat yang kompatibel dengan sesi Alice. Callback createAnswer() diteruskan 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. Setelah 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 tersebut 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 bagus yang menjelaskan proses sinyal dan streaming di video demo Ericsson untuk implementasi WebRTC pertamanya.)

Diagram arsitektur JSEP
Arsitektur JSEP

Setelah proses sinyal berhasil diselesaikan, data dapat di-streaming secara 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 itu rumit.

Diagram arsitektur WebRTC
Arsitektur WebRTC (dari webrtc.org)

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

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

Kode W3C sebelumnya menunjukkan contoh WebRTC yang disederhanakan dari perspektif sinyal. Berikut adalah panduan 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 contoh koneksi Peer WebRTC, yang memiliki RTCPeerConnection lokal dan jarak jauh (serta video lokal dan jarak jauh) di satu halaman web. Hal ini tidak akan menghasilkan sesuatu yang sangat berguna - pemanggil dan yang dipanggil berada di halaman yang sama - tetapi hal ini membuat cara kerja RTCPeerConnection API 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 (yang dipanggil).

Penelepon

  1. Buat RTCPeerConnection baru dan tambahkan streaming dari getUserMedia(): ```js // Servers adalah file konfigurasi opsional. (Lihat diskusi TURN dan STUN nanti.) 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 sinyal karena pemanggil dan yang dipanggil berada di halaman yang sama: js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );

Tujuan panggilan

  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 menemukan satu sama lain 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 melewati gateway NAT dan firewall.

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

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

NAT traversal, jaringan peer-to-peer, dan persyaratan untuk mem-build aplikasi server untuk penemuan dan sinyal pengguna berada di luar cakupan artikel ini. Cukuplah untuk mengatakan bahwa protokol STUN dan ekstensi, TURN, digunakan oleh framework ICE untuk memungkinkan RTCPeerConnection mengatasi NAT traversal 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 balik NAT untuk mengetahui alamat dan port publiknya. (Untuk informasi selengkapnya tentang STUN dan TURN, lihat Mem-build layanan backend yang diperlukan untuk aplikasi WebRTC.)

Menemukan kandidat koneksi
Menemukan kandidat koneksi

Jika UDP gagal, ICE akan mencoba TCP. Jika koneksi langsung gagal - terutama karena NAT traversal dan firewall perusahaan - ICE akan menggunakan server TURN perantara (relay). Dengan kata lain, ICE pertama-tama menggunakan STUN dengan UDP untuk menghubungkan peer secara langsung dan, jika gagal, akan kembali ke server relay 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 tepat untuk mencoba WebRTC, lengkap dengan sinyal dan traversal NAT/firewall menggunakan server STUN, adalah demo chat video di appr.tc. Aplikasi ini menggunakan adapter.js, shim untuk melindungi aplikasi dari perubahan spesifikasi dan perbedaan awalan.

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

Topologi jaringan

WebRTC, seperti yang diterapkan saat ini, hanya mendukung komunikasi satu lawan 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), server yang dapat menangani banyak peserta dan melakukan penerusan streaming selektif, serta pencampuran atau perekaman audio dan video.

Diagram topologi Unit Kontrol Multipoint
Contoh topologi Multipoint Control Unit

Banyak aplikasi WebRTC yang ada hanya menunjukkan komunikasi antara browser web, tetapi server gateway dapat memungkinkan aplikasi WebRTC yang berjalan di browser untuk berinteraksi dengan perangkat, seperti telepon (juga dikenal sebagai PSTN) dan dengan sistem VOIP. Pada Mei 2012, Doubango Telecom merilis klien SIP sipml5 yang dibuat dengan WebRTC dan WebSocket sebagai open source, 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 bencana dalam koper menggunakan sel OpenBTS untuk memungkinkan komunikasi antara ponsel fitur dan komputer melalui WebRTC. Komunikasi telepon tanpa operator.

Demo Tethr/Tropo di Google I/O 2012
Tethr/Tropo: Komunikasi bencana dalam koper

RTCDataChannel API<

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

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

Ada banyak potensi kasus penggunaan untuk API ini, termasuk:

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

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

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

Sintaksis 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 di antara browser, sehingga RTCDataChannel dapat jauh lebih cepat daripada WebSocket meskipun server relay (TURN) diperlukan saat hole-punching untuk mengatasi firewall dan NAT gagal.

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

Untuk 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 di antara browser, atau antara browser dan server.
  • Aplikasi dapat merekam dan mendistribusikan video atau audio tanpa sepengetahuan pengguna.
  • Malware atau virus mungkin diinstal bersama plugin atau aplikasi yang tampaknya tidak berbahaya.

WebRTC memiliki beberapa fitur untuk menghindari masalah ini:

  • Implementasi WebRTC menggunakan protokol aman, seperti DTLS dan SRTP.
  • Enkripsi wajib untuk semua komponen WebRTC, termasuk mekanisme sinyal.
  • WebRTC bukan plugin. Komponennya berjalan di sandbox browser, bukan dalam proses terpisah. Komponen tidak memerlukan penginstalan terpisah dan diperbarui 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.

Diskusi lengkap tentang keamanan untuk media streaming berada di luar cakupan artikel ini. Untuk mengetahui informasi selengkapnya, lihat Arsitektur Keamanan WebRTC yang Diusulkan yang diusulkan oleh IETF.

Kesimpulan

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

Teknologi tidak akan lebih mengganggu daripada ini.

Seperti yang diungkapkan oleh blogger Phil Edholm, "Secara potensial, WebRTC dan HTML5 dapat memungkinkan transformasi yang sama untuk komunikasi real-time seperti yang dilakukan browser asli untuk informasi."

Developer tools

  • Statistik WebRTC untuk sesi yang sedang berlangsung dapat ditemukan di:
    • about://webrtc-internals di Chrome
    • opera://webrtc-internals di Opera
    • about:webrtc di Firefox
      Halaman chrome://webrtc-internals
      screenshot chrome://webrtc-internals
  • Catatan interop lintas browser
  • adapter.js adalah shim JavaScript untuk WebRTC yang dikelola oleh Google dengan bantuan dari komunitas WebRTC yang memisahkan awalan vendor, perbedaan browser, dan perubahan spesifikasi.
  • Untuk mempelajari lebih lanjut proses sinyal WebRTC, periksa output log appr.tc ke konsol.
  • Jika terlalu banyak, Anda dapat menggunakan framework WebRTC atau bahkan layanan WebRTC lengkap.
  • Laporan bug dan permintaan fitur selalu kami tanggapi:

Pelajari lebih lanjut

Standar dan protokol

Ringkasan dukungan WebRTC

MediaStream dan getUserMedia API

  • 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 tinggi
  • 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 baru; Chrome untuk Android 29 dan yang lebih baru (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 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.