Signaling Server — adalah komponen server dari infrastruktur WebRTC yang menyediakan pertukaran metadata antar peer untuk membangun dan mengakhiri koneksi. Berbeda dengan lalu lintas media, sinyal dapat dikirim melalui protokol apa pun — WebSocket, HTTP, XMPP, atau SIP. Menurut MDN Web Docs, 2024, sinyal adalah komponen wajib dari setiap aplikasi WebRTC, karena protokol tidak menentukan cara spesifik untuk bertukar pesan sinyal.
Poin Utama
Signaling Server — adalah layanan jaringan yang bertanggung jawab untuk mengoordinasikan proses pembangunan koneksi WebRTC antara dua atau lebih peer. Server ini tidak mentransmisikan data media (audio, video, data saluran DataChannel), tetapi hanya informasi layanan yang diperlukan untuk menemukan peer dan menyetujui parameter koneksi. Setelah saluran P2P berhasil terbentuk, Signaling Server mungkin tidak diperlukan lagi, tetapi dalam beberapa arsitektur tetap ada untuk pertukaran sinyal selanjutnya (misalnya, mengakhiri panggilan, menambahkan peserta).
Arsitektur sinyal mencakup tiga komponen: Signaling Server, Signal Channel (protokol transport antara klien dan server), dan API klien (biasanya terintegrasi dalam tumpukan WebRTC browser). Spesifikasi WebRTC (W3C, 2024) sengaja tidak menstandarisasi protokol sinyal — pengembang dapat memilih transport apa pun yang sesuai untuk aplikasi mereka. Solusi fleksibel ini memungkinkan penggunaan WebSocket untuk aplikasi web, XMPP untuk sistem obrolan, atau SIP untuk integrasi dengan infrastruktur telekomunikasi.
Sebelum koneksi WebRTC terbentuk, peer harus bertukar tiga jenis pesan: session description (offer dan answer), ICE candidates, dan informasi tentang penghentian/modifikasi sesi. Signaling Server merutekan pesan-pesan ini antar peer, menggunakan identifikasi ruangan atau pengguna untuk pengalamatan. Pola standar — membuat “ruangan” tempat dua peserta terhubung, dan server mentransmisikan pesan dari setiap peserta hanya kepada lawan bicaranya.
Signaling Server mengimplementasikan protokol pembangunan koneksi WebRTC yang khas berikut. Peer terhubung ke server melalui WebSocket (atau transport lain) dan mendaftar di ruangan. Peer A (inisiator) membuat offer (deskripsi SDP dari aliran media keluar) melalui RTCPeerConnection.createOffer(), menetapkannya sebagai local description, dan mengirimkannya ke Signaling Server. Server meneruskan offer ke peer B. Peer B menerima offer, menetapkannya sebagai remote description, membuat answer melalui createAnswer(), menetapkannya sebagai local description, dan mengirimkannya kembali melalui server. Proses ini disebut SDP Offer/Answer.
Secara paralel dengan pertukaran SDP, setiap peer mengumpulkan ICE candidates (host, srflx, relay) dan mengirimkannya melalui Signaling Server ke peer lain. Peer jarak jauh menambahkan kandidat yang diterima melalui RTCPeerConnection.addIceCandidate(). Proses ICE memeriksa semua kombinasi kandidat untuk menemukan jalur yang berfungsi. Setelah jalur yang berfungsi ditemukan (biasanya dalam 1–5 detik), lalu lintas media mulai ditransmisikan langsung antar peer, dan Signaling Server tidak lagi berpartisipasi dalam transmisi data — perannya selesai hingga acara layanan berikutnya (mengakhiri panggilan, mengubah kualitas aliran).
Untuk pengalamatan pesan, Signaling Server menggunakan mekanisme ruangan (rooms) atau saluran. Setiap sesi WebRTC baru membuat ruangan unik dengan pengenal (biasanya UUID). Inisiator membuat ruangan dan menunggu koneksi peer kedua. Peer kedua terhubung ke ruangan melalui ID yang diperoleh melalui saluran eksternal (misalnya, tautan undangan). Server menyimpan peta ruangan, di mana setiap ID sesuai dengan daftar klien yang terhubung. Ketika jumlah peserta mencapai dua, server mulai mentransmisikan pesan sinyal di antara mereka.
Signaling Server dapat menggunakan protokol transport yang berbeda, masing-masing dengan kelebihan dan kekurangannya sendiri. Pemilihan protokol tergantung pada jenis aplikasi, batasan infrastruktur, dan persyaratan kompatibilitas. Di bawah ini adalah protokol yang paling umum dan karakteristiknya.
| Protokol | Transport | Kelebihan | Kekurangan |
|---|---|---|---|
| WebSocket | TCP | Full-duplex, latensi rendah, terintegrasi di browser | Kompleksitas penskalaan, pemblokiran proxy |
| HTTP/SSE | TCP | Kompatibilitas dengan infrastruktur apa pun, kesederhanaan implementasi | Hanya satu arah (server-klien), memerlukan Polling |
| XMPP | TCP | Terstandarisasi, dukungan autentikasi, dapat diperluas | Berlebihan untuk skenario sederhana, overhead XML |
| SIP | UDP/TCP | Integrasi dengan VoIP dan infrastruktur telepon | Kompleks, tidak asli untuk browser |
| MQTT | TCP | Ringan, bekerja di lingkungan IoT, publish/subscribe | Memerlukan broker, latensi tambahan |
WebSocket adalah protokol paling populer untuk Signaling Server di aplikasi web. Ini menyediakan komunikasi full-duplex, yang penting untuk pertukaran asinkron SDP dan kandidat ICE, dan didukung secara native oleh semua browser modern melalui WebSocket API. Implementasi server WebSocket tersedia di semua platform populer (Node.js, Python, Java, Go). Untuk aplikasi dengan jutaan pengguna, solusi WebSocket yang dapat diskalakan berdasarkan Redis Pub/Sub atau Kafka digunakan untuk sinkronisasi antar instance Signaling Server.
Mari kita lihat implementasi sederhana Signaling Server di Node.js menggunakan pustaka ws (WebSocket) dan server HTTP bawaan. Server mendukung pendaftaran pengguna, pembuatan ruangan, dan transmisi pesan antar peserta.
const WebSocket = require("ws");
const server = new WebSocket.Server({ port: 8080 });
const rooms = new Map();
server.on("connection", (ws) => {
ws.roomId = null;
ws.on("message", (data) => {
const msg = JSON.parse(data);
switch (msg.type) {
case "join":
handleJoin(ws, msg.roomId);
break;
case "offer":
case "answer":
case "ice-candidate":
relayToPeer(ws, msg);
break;
case "leave":
handleLeave(ws);
break;
}
});
ws.on("close", () => handleLeave(ws));
});
function handleJoin(ws, roomId) {
if (!rooms.has(roomId)) {
rooms.set(roomId, []);
}
const room = rooms.get(roomId);
room.push(ws);
ws.roomId = roomId;
if (room.length === 2) {
room[0].send(JSON.stringify({ type: "peer-joined" }));
room[1].send(JSON.stringify({ type: "peer-joined" }));
}
}
function relayToPeer(sender, msg) {
const room = rooms.get(sender.roomId);
if (!room) return;
room.forEach(peer => {
if (peer !== sender && peer.readyState === WebSocket.OPEN) {
peer.send(JSON.stringify(msg));
}
});
}
function handleLeave(ws) {
if (!ws.roomId) return;
const room = rooms.get(ws.roomId);
if (!room) return;
const idx = room.indexOf(ws);
if (idx !== -1) room.splice(idx, 1);
if (room.length === 0) rooms.delete(ws.roomId);
}
Signaling Server ini mengimplementasikan fungsionalitas dasar: terhubung ke ruangan, mentransmisikan pesan WebRTC (offer, answer, ice-candidate) antara dua peer, dan mengelola pemutusan koneksi. Server menggunakan Map untuk menyimpan ruangan dengan klien WebSocket yang terhubung. Fungsi relayToPeer mengirimkan pesan ke semua peserta di ruangan kecuali pengirim. Untuk produksi, diperlukan konfirmasi jenis pesan, penanganan kesalahan parsing JSON, dan mekanisme heartbeat untuk mendeteksi koneksi yang terputus.
Di sisi klien, Signaling Server diintegrasikan melalui WebSocket API browser. Klien membuat koneksi ke server, mengirim permintaan untuk bergabung ke ruangan, kemudian memproses pesan WebRTC yang masuk, meneruskannya ke RTCPeerConnection melalui setRemoteDescription() dan addIceCandidate(). Kode klien juga mengirimkan SDP dan kandidat ICE miliknya ke server, yang diperoleh dari RTCPeerConnection melalui peristiwa onicecandidate dan setelah membuat offer/answer.
Signaling Server mentransmisikan dua jenis metadata utama: SDP (Session Description Protocol) dan ICE candidates. SDP menggambarkan parameter aliran media — codec, frekuensi pengambilan sampel, jumlah saluran, arah transmisi (sendrecv, sendonly, recvonly, inactive). ICE candidates berisi alamat jaringan (lokal, diperoleh dari STUN, relay dari TURN) di mana peer dapat dijangkau untuk koneksi.
SDP disajikan dalam format teks yang berisi sesi dan bagian media. Bagian sesi menggambarkan parameter umum (identifikasi sesi, versi, nama), bagian media — setiap aliran media (audio, video, DataChannel) dengan codec, port, dan protokolnya. Kandidat ICE berisi foundation (pengidentifikasi untuk pengelompokan), priority, alamat IP, port, tipe (host, srflx, relay), dan protokol (UDP, TCP). Setiap candidate juga menyertakan atribut ufrag (username fragment) yang menghubungkannya dengan proses ICE tertentu.
Trickle ICE secara signifikan mempercepat pembangunan koneksi WebRTC. Alih-alih menunggu pengumpulan penuh semua kandidat ICE (yang bisa memakan waktu 2–10 detik di jaringan kompleks), setiap kandidat dikirim ke Signaling Server segera setelah ditemukan. Peer jarak jauh menerima kandidat dan segera mulai memeriksa koneksi melalui kerangka ICE. Ini mengurangi waktu pembangunan koneksi menjadi 500–1500 ms di sebagian besar kasus.
Pertanyaan yang Sering Diajukan
Signaling Server — adalah “koordinator” sebelum panggilan. Ini membantu dua perangkat menemukan satu sama lain dan menyepakati bagaimana mereka akan berkomunikasi. Setelah perangkat “berkenalan” dan menyepakati, server tidak lagi diperlukan — mereka berkomunikasi langsung.
WebRTC tidak menentukan protokol sinyal agar pengembang dapat memilih transport yang paling sesuai. Browser tidak memiliki mekanisme bawaan untuk menemukan pengguna lain — tugas ini diselesaikan oleh Signaling Server. Ini berfungsi sebagai “kurir”, mengirimkan undangan dan pengaturan koneksi antar peserta panggilan.
WebSocket — pilihan optimal untuk sebagian besar aplikasi web: full-duplex, didukung secara native oleh browser, sederhana untuk diimplementasikan. Untuk integrasi dengan infrastruktur VoIP yang ada, pilih SIP. Untuk aplikasi obrolan dengan fitur kaya — XMPP. Untuk skenario IoT — MQTT.
Untuk menskalakan Signaling Server gunakan penskalaan horizontal dengan sinkronisasi melalui Redis Pub/Sub atau Kafka. Setiap instance server memproses bagiannya sendiri dari koneksi WebSocket, dan untuk routing pesan antar server digunakan bus data bersama. Pendekatan ini memungkinkan pemrosesan jutaan sesi sinyal secara simultan.
Signaling Server hanya penting pada tahap pembangunan koneksi. Jika server untuk sementara tidak tersedia, panggilan WebRTC yang aktif tetap berlanjut — lalu lintas media berjalan langsung antar peer. Masalah hanya muncul saat mencoba membangun koneksi baru. Untuk keandalan, gunakan klasterisasi server dan saluran sinyal cadangan.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga