Press ESC to close

Menyelinap ke Jantung Google Meet: Monkey Patching RTCPeerConnection

Sebagai bagian dari pengembangan NetMeter Web, tantangan untuk mengukur website berbasis WebRTC adalah hal yang cukup vital. WebRTC itu benar-benar liar, real-time, tidak tercatat di DevTools Network sama sekali, namun sangat efisien dalam pengiriman paket data.

Salah satu situs yang kita jadikan rujukan utama untuk benchmarking bandwidth website berbasis WebRTC bukan tidak lain adalah Google Meet.

Google Meet merupakan situs WebRTC terbesar sejagat raya. Ia bukan hanya aplikasi rapat, Meet adalah mesin komunikasi realtime yang sudah ditempa oleh miliaran menit meeting per hari. Dan berbeda dengan Zoom yang merupakan aplikasi native, Meet beroperasi sepenuhnya di browser.

Inilah yang kita sukai, browser webapp! 😃

Alasan pemilihan Google Meet untuk Benchmarking adalah mereka gratis. Karna kami suka turbo yang gratis-gratis. 😆


Bisakah kita memantau Bandwidth WebRTC?

Tidak seperti fetch atau XHR yang masih bisa ditangkap melalui patching standar, WebRTC adalah “jalur liar” yang tidak melewati HTTP sama sekali. Ia berjalan di atas protokol UDP (atau TCP via TURN) yang dipilih secara otomatis oleh browser.

Masalah utama saat mengukur bandwidth situs berbasis WebRTC adalah:

  1. Tidak ada Request/Response: WebRTC mengirim paket audio/video melalui stream RTP berkelanjutan.
  2. DevTools Buta: Tab Network di browser tidak mencatat trafik SRTP (Secure Real-time Transport Protocol).
  3. Dinamis: Google Meet secara aktif menaik-turunkan bitrate tergantung kesehatan koneksi internet.

Untungnya, browser berbasis Chromium memiliki “ruang rahasia” bernama chrome://webrtc-internals. Di sinilah kita bisa melihat statistik mentah seperti candidate-pair, packet loss, dan bitrate. Namun, karena halaman ini tidak bisa diakses oleh Extension (karena alasan keamanan), kita harus menggunakan Monkey Patching.

chrome://webrtc-internals (ICE bytesReceived + bytesSent)

Pada halaman inilah Chrome menampilkan seluruh statistik internal WebRTC, termasuk ICE, DTLS, SRTP, jitter, RTT, dan tentu saja… bandwidth.

Bagian terpentingnya ada pada candidate-pair, untuk kasus Google Meet. Di sana kita bisa melihat:

  • bytesSent
  • bytesReceived
  • availableOutgoingBitrate
  • availableIncomingBitrate
  • currentRoundTripTime
  • state: succeeded/frozen/disconnected

Masalahnya, halaman chrome://webrtc-internals adalah halaman privilege browser. Extension tidak bisa meng-scrape halaman chrome:// karena alasan keamanan (CORS dan security policy browser).

Lantas bagaimana cara NetMeter Web “mengintip” penggunaan bandwidth Meet?


Menyelinap ke Jantung WebRTC: RTCPeerConnection

Untuk menangkap trafik WebRTC, kita tidak punya pilihan selain melakukan intercept langsung pada browser API. Kita tahu bahwa RTCPeerConnection adalah gerbang utama segala komunikasi audio/video.

Di RTCPeerConnection inilah NetMeter Web melakukan manuver Monkey Patching.

Kita tidak mengubah kode sumber Google Meet (karena tidak mungkin), melainkan kita membungkus (wrap) konstruktor asli browser dengan logika kita sendiri. Tujuannya sederhana: Setiap kali Google Meet membuat koneksi baru, NetMeter harus tahu.

Berikut adalah inti dari teknik patching yang kami gunakan. Kode ini disederhanakan untuk fokus pada bagaimana kami menyadap statistik tanpa merusak jalannya aplikasi:

const patchWebRTC = () => {
    ...
    const OriginalRTCPeerConnection = RTCPeerConnection;
    const peerConnections = new WeakMap(); // Simpan state tanpa memory leak

    // 2. Logika Monitoring: Inti dari NetMeter Web
    const monitorStats = async (pc: RTCPeerConnection) => {
      const lastStats = { bytesSent: 0, bytesReceived: 0 };
      ...
      // Polling setiap 2 detik
      const intervalId = setInterval(async () => {
        try {
          // Mengambil data langsung dari Native Browser API
          const stats = await pc.getStats();
          let s = 0, r = 0;
          
          stats.forEach((rep) => {
            // Filter hanya paket RTP (Media) yang relevan
            if (rep.type === "outbound-rtp" && !rep.isRemote) s += rep.bytesSent || 0;
            if (rep.type === "inbound-rtp" && !rep.isRemote) r += rep.bytesReceived || 0;
          });

          // Hitung Delta (Selisih) dari detik sebelumnya
          const dS = s - lastStats.bytesSent;
          const dR = r - lastStats.bytesReceived;

          // Kirim ke UI NetMeter jika ada aktivitas
          if (dS > 0 || dR > 0) {
              notifyNetMeter(dS, dR, "WEBRTC");
          }

          // Update state terakhir
          lastStats.bytesSent = s;
          lastStats.bytesReceived = r;
        } catch (e) { /* Silent fail agar tidak mengganggu meeting */ }
      }, 2000);
    };

    // 3. Class Wrapper: "Topeng" NetMeter
    class PatchedRTCPeerConnection extends OriginalRTCPeerConnection {
      constructor(...args: any[]) {
        super(...args);
        const pc = this;

        // Pasang penyadap statistik segera setelah koneksi dibuat
        monitorStats(pc);

      }
    }

    // 4. Mengganti API Browser dengan versi Patched
    try {
      // Injeksi Class kita ke Global Window
      (window as any).RTCPeerConnection = PatchedRTCPeerConnection;

      // NOTE: Restore Prototype Chain
      // Teknik ini memastikan library pihak ketiga (seperti adapter.js) 
      // tidak sadar bahwa fungsi aslinya telah diganti.
      (window as any).RTCPeerConnection.prototype = OriginalRTCPeerConnection.prototype;
      
      // Copy static methods agar kompatibilitas terjaga
      Object.keys(OriginalRTCPeerConnection).forEach((key) => {
        (window as any).RTCPeerConnection[key] = (OriginalRTCPeerConnection as any)[key];
      });
    } catch (e) {}
};

Ada tiga trik utama dalam kode tersebut yang menjamin NetMeter Web berjalan mulus di situs serumit Google Meet:

  1. Penggunaan WeakMap: Kita menggunakan WeakMap untuk menyimpan referensi koneksi. Ini sangat krusial. Jika kita menggunakan Array biasa, referensi ke objek koneksi tidak akan pernah dihapus oleh Garbage Collector browser meskipun meeting sudah selesai, yang akhirnya menyebabkan memory leak (browser jadi berat).
  2. Prototype Restoration: Perhatikan bagian (window as any).RTCPeerConnection.prototype = .... Banyak aplikasi WebRTC canggih melakukan pengecekan integritas (integrity check). Jika mereka mendeteksi bahwa fungsi RTCPeerConnection berbeda dari aslinya, aplikasi bisa menolak berjalan. Dengan mengembalikan prototype chain ke aslinya, NetMeter beroperasi dalam Stealth Mode. Google Meet mengira ia memanggil fungsi native, padahal ia memanggil fungsi kita.
  3. Delta Calculation: API getStats() dari browser memberikan angka yang bersifat kumulatif. Karena itu, kita perlu rumus matematika sederhana: Delta = TotalSaatIni - TotalSebelumnya. Karna yang ingin kita lihat adalah: “Berapa banyak data yang lewat dalam 2 detik terakhir?”

Dengan cara ini, NetMeter tidak melaporkan “Total kuota yang sudah habis”, melainkan melaporkan “Aktivitas data yang sedang terjadi saat ini” (incremental).

NetMeter Web bandwidth monitoring – Google Meet

Sedikit Pelajaran Yang Bisa Diambil

Mengukur bandwidth WebRTC, khususnya pada situs besar seperti Google Meet, bukanlah pekerjaan sederhana. Ada begitu banyak mekanisme internal, jalur non-HTTP, serta adaptasi bitrate yang membuat perhitungan manual mustahil.

Jika kalian melihat trafik WebRTC pada Google Meet, dan bertanya kenapa total bandwidth cukup rendah meskipun meeting lama?, maka itulah kelebihan WebRTC. WebRTC memprioritaskan stability bukan bitrate yang tinggi.

Pengalaman ini membuat saya menyadari satu hal:

WebRTC adalah teknologi yang sangat indah, hemat sekaligus sangat efisien untuk jalur komunikasi.

Muhammad K Huda

A non exhausted blogger person within fullstack engineer (spicy food), open source religion, self-taught driver and maybe you know or don't like it. Simply says, Hello from Me!

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Cek untuk notifikasi e-mail jika komentar dibalas.

This site uses Akismet to reduce spam. Learn how your comment data is processed.