Memulai koneksi pembanding

Koneksi peer adalah bagian dari spesifikasi WebRTC yang menangani koneksi dua aplikasi di komputer yang berbeda untuk berkomunikasi menggunakan protokol peer-to-peer. Komunikasi antar-peer dapat berupa video, audio, atau data biner arbitrer (untuk klien yang mendukung RTCDataChannel API). Untuk menemukan cara dua peer dapat terhubung, kedua klien harus memberikan konfigurasi Server ICE. Server ini adalah server STUN atau TURN, dan perannya adalah menyediakan kandidat ICE untuk setiap klien yang kemudian ditransfer ke peer jarak jauh. Transfer kandidat ICE ini biasanya disebut pensinyalan.

Pemberian isyarat

Spesifikasi WebRTC mencakup API untuk berkomunikasi dengan Server ICE (Internet Connectivity Establishment), tetapi komponen pensinyalan bukan bagian dari spesifikasi tersebut. Sinyal diperlukan agar dua peer dapat berbagi cara mereka harus terhubung. Biasanya, masalah ini diselesaikan melalui Web API berbasis HTTP reguler (yaitu, layanan REST atau mekanisme RPC lainnya) tempat aplikasi web dapat meneruskan informasi yang diperlukan sebelum koneksi peer dimulai.

Cuplikan kode berikut menunjukkan cara layanan sinyal fiktif ini dapat digunakan untuk mengirim dan menerima pesan secara asinkron. Ini akan digunakan dalam contoh lainnya dalam 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!');

Pensinyalan dapat diterapkan dalam banyak cara yang berbeda, dan spesifikasi WebRTC tidak lebih memilih solusi tertentu.

Memulai koneksi pembanding

Setiap koneksi peer ditangani oleh objek RTCPeerConnection. Konstruktor untuk class ini menggunakan satu objek RTCConfiguration sebagai parameternya. Objek ini menentukan cara penyiapan koneksi peer 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 yang memanggil atau peer yang menerima. Setelah penawaran atau jawaban SDP dibuat, penawaran atau jawaban tersebut harus dikirim ke peer jarak jauh melalui channel yang berbeda. Penerusan objek SDP ke peer jarak jauh disebut pensinyalan dan tidak tercakup dalam spesifikasi WebRTC.

Untuk memulai penyiapan koneksi peer dari sisi panggilan, kita membuat objek RTCPeerConnection, lalu memanggil createOffer() untuk membuat objek RTCSessionDescription. Deskripsi sesi ini ditetapkan sebagai deskripsi lokal menggunakan setLocalDescription(), lalu dikirim melalui saluran pensinyalan kami ke sisi penerima. Kita juga menyiapkan pendengar ke saluran sinyal untuk saat jawaban atas 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 selesai, kita akan menyetel 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 pemanggil melalui server pensinyalan 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 peer menetapkan deskripsi sesi lokal dan jarak jauh, mereka mengetahui kemampuan peer jarak jauh. Hal ini tidak berarti bahwa koneksi antar-peer sudah siap. Agar ini berfungsi, kita perlu mengumpulkan kandidat ICE di setiap peer dan mentransfernya (melalui saluran sinyal) ke peer lainnya.

Kandidat ICE

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

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

ICE bertahap

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

Meskipun peer dapat menunggu hingga pengumpulan ICE selesai, biasanya lebih efisien menggunakan teknik "ICE bertahap" dan mengirimkan setiap kandidat ICE ke peer jarak jauh saat ditemukan. Hal ini akan mengurangi waktu penyiapan konektivitas antar-perangkat secara signifikan dan memungkinkan panggilan video dimulai dengan lebih sedikit penundaan.

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

// 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 dapat mengharapkan status koneksi peer kita akan berubah menjadi status terhubung. Untuk mendeteksinya, 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