Memulai koneksi pembanding

Koneksi peer adalah bagian dari spesifikasi WebRTC yang berkaitan dengan menghubungkan dua aplikasi di komputer yang berbeda untuk berkomunikasi menggunakan protokol peer-to-peer. Komunikasi antar-peer dapat berupa data biner video, audio, atau arbitrer (untuk klien yang mendukung RTCDataChannel API). Untuk mengetahui cara dua pembanding terhubung, kedua klien harus menyediakan konfigurasi Server ICE. Ini dapat berupa STUN atau Flip-server, dan peran mereka adalah menyediakan kandidat ICE untuk setiap klien yang kemudian ditransfer ke peer jarak jauh. Transfer kandidat ICE ini biasanya disebut pemberian sinyal.

Sinyal

Spesifikasi WebRTC mencakup API untuk berkomunikasi dengan Server ICE (Internet Connectivity Provisioningment), tetapi komponen sinyal bukanlah bagiannya. Pensinyalan diperlukan agar dua pembanding dapat berbagi cara menghubungkan. Biasanya ini diselesaikan melalui Web API berbasis HTTP biasa (yaitu, layanan REST atau mekanisme RPC lainnya) tempat aplikasi web dapat menyampaikan informasi yang diperlukan sebelum koneksi peer dimulai.

Cuplikan kode berikut menunjukkan cara layanan pensinyalan fiktif ini dapat digunakan untuk mengirim dan menerima pesan secara asinkron. Ini akan digunakan dalam contoh yang tersisa di panduan ini jika diperlukan.

// Set up an asynchronous communication channel that will be
// used during the peer connection setup
const signalingChannel = new SignalingChannel(remoteClientId);
signalingChannel.addEventListener('message', message => {
    // New message from remote client received
});

// Send an asynchronous message to the remote client
signalingChannel.send('Hello!');

Sinyal dapat diterapkan dengan berbagai cara, dan spesifikasi WebRTC tidak memilih solusi tertentu.

Memulai koneksi pembanding

Setiap koneksi pembanding ditangani oleh objek RTCPeerConnection. Konstruktor untuk class ini mengambil satu objek RTCConfiguration sebagai parameternya. Objek ini menentukan cara koneksi pembanding disiapkan dan harus berisi informasi tentang server ICE yang akan digunakan.

Setelah RTCPeerConnection dibuat, kita perlu membuat penawaran atau jawaban SDP, bergantung pada apakah kita adalah peer panggilan atau penerima peer. Setelah dibuat, penawaran atau jawaban SDP harus dikirimkan ke peer jarak jauh melalui saluran lain. Meneruskan objek SDP ke pembanding jarak jauh disebut sinyal dan tidak dicakup oleh spesifikasi WebRTC.

Untuk memulai penyiapan koneksi pembanding dari sisi panggilan, kita membuat objek RTCPeerConnection, lalu memanggil createOffer() untuk membuat objek RTCSessionDescription. Deskripsi sesi ini disetel sebagai deskripsi lokal menggunakan setLocalDescription(), lalu dikirim melalui saluran sinyal kami ke sisi penerima. Kami juga menyiapkan pemroses ke saluran sinyal kami saat jawaban untuk deskripsi sesi yang ditawarkan diterima dari sisi penerima.

async function makeCall() {
    const configuration = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]}
    const peerConnection = new RTCPeerConnection(configuration);
    signalingChannel.addEventListener('message', async message => {
        if (message.answer) {
            const remoteDesc = new RTCSessionDescription(message.answer);
            await peerConnection.setRemoteDescription(remoteDesc);
        }
    });
    const offer = await peerConnection.createOffer();
    await peerConnection.setLocalDescription(offer);
    signalingChannel.send({'offer': offer});
}

Di sisi penerima, kita menunggu penawaran masuk sebelum membuat instance RTCPeerConnection. Setelah itu, kita menetapkan penawaran yang diterima menggunakan setRemoteDescription(). Selanjutnya, kita memanggil createAnswer() untuk membuat jawaban atas penawaran yang diterima. Jawaban ini ditetapkan sebagai deskripsi lokal menggunakan setLocalDescription(), lalu dikirim ke sisi panggilan melalui server sinyal kami.

const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
    if (message.offer) {
        peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
        const answer = await peerConnection.createAnswer();
        await peerConnection.setLocalDescription(answer);
        signalingChannel.send({'answer': answer});
    }
});

Setelah kedua pembanding menetapkan deskripsi sesi lokal dan jarak jauh, mereka mengetahui kemampuan pembanding jarak jauh. Ini tidak berarti bahwa koneksi antar-peer sudah siap. Agar berfungsi, kita perlu mengumpulkan kandidat ICE di setiap pembanding dan mentransfer (melalui saluran sinyal) ke pembanding lainnya.

Kandidat ICE

Sebelum dua pembanding dapat berkomunikasi menggunakan WebRTC, mereka harus bertukar informasi konektivitas. Karena kondisi jaringan dapat bervariasi bergantung pada sejumlah faktor, layanan eksternal biasanya digunakan untuk menemukan calon kandidat untuk terhubung ke pembanding. Layanan ini disebut ICE dan menggunakan server STUN atau Flip. STUN adalah singkatan dari Session Traversal Utilities for NAT, dan biasanya digunakan secara tidak langsung di sebagian besar aplikasi WebRTC.

Flip (Traversal Using Relay NAT) adalah solusi yang lebih canggih yang menggabungkan protokol STUN dan sebagian besar layanan berbasis WebRTC komersial menggunakan server Flip untuk membuat koneksi antar-peer. WebRTC API mendukung STUN dan turn secara langsung, dan dikumpulkan dengan persyaratan yang lebih lengkap tentang Konektivitas Internet. Saat membuat koneksi WebRTC, kami biasanya menyediakan satu atau beberapa server ICE dalam konfigurasi untuk objek RTCPeerConnection.

Trickle ICE

Setelah objek RTCPeerConnection dibuat, framework yang mendasarinya menggunakan server ICE yang disediakan untuk mengumpulkan kandidat untuk pembentukan konektivitas (kandidat ICE). Peristiwa icegatheringstatechange pada RTCPeerConnection memberitahukan status pengumpulan ICE (new, gathering, atau complete).

Meskipun memungkinkan bagi sesama untuk menunggu hingga pengumpulan ICE selesai, biasanya akan jauh lebih efisien untuk menggunakan teknik "tetesan es" dan mengirimkan setiap kandidat ICE ke pembanding jarak jauh saat ditemukan. Tindakan ini akan mengurangi waktu penyiapan konektivitas pembanding secara signifikan dan memungkinkan panggilan video untuk memulai dengan penundaan yang lebih sedikit.

Untuk mengumpulkan kandidat ICE, cukup tambahkan pemroses untuk peristiwa icecandidate. RTCPeerConnectionIceEvent yang dihasilkan pada pemroses tersebut akan berisi properti candidate yang mewakili kandidat baru yang harus dikirim ke peer jarak jauh (Lihat Pensinyalan).

// Listen for local ICE candidates on the local RTCPeerConnection
peerConnection.addEventListener('icecandidate', event => {
    if (event.candidate) {
        signalingChannel.send({'new-ice-candidate': event.candidate});
    }
});

// Listen for remote ICE candidates and add them to the local RTCPeerConnection
signalingChannel.addEventListener('message', async message => {
    if (message.iceCandidate) {
        try {
            await peerConnection.addIceCandidate(message.iceCandidate);
        } catch (e) {
            console.error('Error adding received ice candidate', e);
        }
    }
});

Koneksi terjalin

Setelah kandidat ICE diterima, kita akan memperkirakan status untuk koneksi peer ini pada akhirnya akan berubah ke status terhubung. Untuk mendeteksi hal ini, kita menambahkan pemroses ke RTCPeerConnection tempat kita memproses peristiwa connectionstatechange.

// Listen for connectionstatechange on the local RTCPeerConnection
peerConnection.addEventListener('connectionstatechange', event => {
    if (peerConnection.connectionState === 'connected') {
        // Peers connected!
    }
});

Dokumentasi API RTCPeerConnection