Di Voximplant, kami telah menggunakan WebRTC sejak awal: pertama sebagai alternatif untuk Flash untuk panggilan suara dan video, dan kemudian sebagai pengganti yang lengkap. Teknologi ini telah menempuh jalan perkembangan yang panjang dan menyakitkan, hanya baru-baru ini semua browser utama telah mulai mendukungnya, ada kesulitan dengan transfer layar, beberapa aliran video, dan kadang-kadang browser mogok hanya jika Anda mematikan dan menghidupkan aliran video. Akumulasi pengalaman memungkinkan kami menerjemahkan artikel menarik untuk Habr, dan hari ini kami menyampaikan kata tersebut kepada Lee Sylvester dari Xirsys, yang akan berbicara tentang debugging (video) panggilan di Chrome, Firefox, Safari, dan Edge. Debugging WebRTC tidak mudah, kami bahkan memiliki
instruksi khusus untuk menghapus log di browser populer. Dan apa yang dimiliki Lee - Anda akan menemukan jawabannya (spoiler: banyak dari semuanya, termasuk WireShark).
Sisi gelap WebRTC
Saat bekerja di Xirsys, saya melihat beberapa aplikasi keren yang menggunakan WebRTC. Tetapi sementara sekelompok kecil pengembang menciptakan hal-hal berteknologi tinggi, sebagian besar programmer bahkan tidak dapat mulai menggunakan WebRTC. Mengapa Dan semuanya sederhana. Ini rumit.
Banyak dari kita yang akrab dengan aplikasi web biasa. Aplikasi semacam itu memiliki klien yang mengirimkan permintaan dan server yang menanggapi permintaan ini. Proses yang sederhana, linier, dan mudah diprediksi. Jika terjadi kesalahan, kita biasanya tahu di mana harus melihat log dan apa yang bisa terjadi. Tetapi dengan WebRTC, semuanya tidak begitu sederhana.
Sinkronisasi
Jika Anda pernah menulis aplikasi multi-utas, maka Anda mungkin tahu tentang sakit kepala yang diberikan pengembangan ini. Penerbangan, memori buruk - tetapi paling sering hanya bug yang sulit ditemukan.
WebRTC bersifat asinkron. Dan ini sama sekali bukan asinkron AJAX sederhana. Untuk menarik analogi, ini adalah beberapa permintaan AJAX yang diluncurkan secara bersamaan yang mencoba untuk merekonsiliasi data pada dua komputer. Itu masih hiburan.
Lewati ladang tambang NAT
Membuat aplikasi web dilakukan untuk mengembangkan sesuatu yang berjalan di server dan menanggapi permintaan. Hal terburuk yang bisa terjadi adalah port yang tidak terbuka di IPTables. Ini dirawat dalam 2 menit. Anda tidak bisa mengatakan tentang WebRTC.
Server web, bahkan perangkat lunaknya, tetapi perangkat keras, adalah perangkat dengan alamat IP publik. Mereka dibuat dapat diakses dari mana saja. Dan WebRTC dibuat untuk mengirim dan menerima data dari komputer pengguna. Yang biasanya memiliki alamat IP 192.168. Sesuatu dan tidak menyala dengan keinginan untuk menanggapi permintaan jaringan.
Para penulis WebRTC tahu tentang ini, sehingga mesin akan memilah-milah metode koneksi yang berbeda, dalam upaya untuk membuat koneksi antara dua komputer yang tidak terlalu dirancang untuk itu.
Di mana memulai debugging
Pada artikel ini saya berbicara tentang alat dasar untuk menyelesaikan masalah yang paling populer. Tetapi sebelum itu, mari kita lihat bagaimana WebRTC biasanya membangun koneksi.
Bagaimana WebRTC membuat koneksi
Semua koneksi WebRTC memerlukan sedikit bantuan dari protokol pensinyalan. “Sedikit bantuan” adalah server dan protokol Anda sendiri yang dengannya pemanggil akan dapat berkomunikasi dengan orang yang ia panggil sebelum membuat koneksi Peer-to-peer.
WebRTC akan menggunakan protokol pensinyalan untuk mengirimkan informasi tentang alamat IP, kemampuan untuk menangkap dan memutar suara dan video, topologi jaringan, dan data yang dikirimkan.
Protokol yang umum digunakan adalah COMET (atau SIP - catatan penerjemah) dan soket web. WebRTC tidak membatasi pengembang untuk apa pun, sehingga Anda dapat menggunakan apa pun yang Anda suka, setidaknya mentransfer data melalui Notepad dan salin-tempel (dilakukan di salah satu bengkel, berfungsi - lagi penerjemah). Pensinyalan yang terhubung ke kedua komputer memungkinkan Anda memulai koneksi yang sudah melalui WebRTC.
Tawarkan dan jawab
Koneksi WebRTC menggunakan "offer" dan "answer":
- Penggagas koneksi menciptakan dan meneruskan ke "penawaran" pihak lain.
- Pihak lain menerima "tawaran", menciptakan "respons" dan meneruskannya kembali.
- Inisiator koneksi menerima "jawaban".
Ini dalam teori. Dalam praktiknya, pertukaran sapa tidak terlihat begitu sederhana.
- Sebelum mentransmisikan "penawaran", inisiator koneksi membuat instance dari RTCPeerConnection dan menerima darinya paket teks "SDP" (Protokol Deskripsi Sesi) menggunakan rtcPeerConnection.createOffer () ; Paket ini menjelaskan kemampuan untuk menerima / mengirimkan suara dan video untuk browser.
- Isi paket SDP ditetapkan sebagai "deskripsi sisi lokal koneksi" menggunakan rtcPeerConnection.setLocalDescription () .
- Paket dikirim ke sisi lain, di mana isinya diatur sebagai "deskripsi sisi lain koneksi" menggunakan rtcPeerConnection.setRemoteDescription () .
- Di sisi lain koneksi, paket SDP-nya dibuat menggunakan rtcPeerConnection.createAnswer () , isinya ditetapkan sebagai "deskripsi sisi lokal koneksi".
- Paket dilewatkan ke inisiator koneksi, yang menetapkan isinya sebagai "deskripsi sisi lain koneksi".
Dan hanya setelah semua tindakan, kedua pihak yang terhubung mengetahui kemampuan masing-masing untuk menerima dan mengirim suara / video.
Kandidat ICE
Tetapi kemampuan untuk bekerja dengan media tidak cukup. Bagaimanapun, pihak-pihak yang berkontrak belum mengatakan apa-apa tentang keadaan jaringan.
Anda dapat mengetahui codec video mana yang didukung browser dan apakah ada kamera di laptop hampir secara instan. Butuh waktu untuk mengetahui alamat IP eksternal Anda dan logika operasi NAT, dan informasi tentang status jaringan dipertukarkan ketika informasi ini diterima.
Berkat teknologi Trickle ICE (tidak didukung oleh semua browser - catatan penerjemah), koneksi antara dua perangkat WebRTC dapat dibuat kapan saja - segera setelah "kandidat" yang cocok ditemukan.
Pengembang harus berlangganan ke acara
onicecandidate (semua huruf kecil!) Dan meneruskan paket SDP yang diterima ke sisi lain, di mana paket tersebut harus ditransmisikan oleh WebRTC menggunakan metode
addIceCandidate (dan di sini, kejutan, huruf kapital). Ini bekerja dua arah.
Koneksi
WebRTC menggunakan hal-hal seperti STUN (Session Traversal Utilities for NAT) dan TURN (Traversal Menggunakan Relay di sekitar NAT) untuk membuat koneksi. Kedengarannya menakutkan, tetapi pada kenyataannya hanya ada dua protokol jaringan.
STUN server
Protokol pertama dari kedua protokol ini sedikit lebih rumit daripada server gema. Saat menghubungkan peserta, mereka ingin menjelaskan cara menghubungkan mereka, mereka membutuhkan alamat IP publik mereka. Dan kemungkinan besar itu bukan alamat IP komputer, perangkat publik jarang dialokasikan untuk perangkat pengguna. Seluruh teknologi NAT diciptakan agar tidak mengisolasi. Untuk tetap mengetahui alamat publik Anda, browser membuat permintaan ke server STUN. Melewati NAT, paket jaringan mengubah alamat pengirim ke publik. Setelah menerima paket dengan permintaan, server STUN menyalin alamat pengirim untuk muatannya dan mengirimkan paket kembali. Melewati NAT di arah yang berlawanan, paket kehilangan alamat IP publiknya, tetapi salinan alamat ini tetap dalam muatan, di mana WebRTC dapat membacanya.
HIDUPKAN server
Server TURN menggunakan ekstensi protokol STUN. Paket, header, dan hal yang sama:
perintah . Server adalah proxy: kedua klien terhubung melalui port
alokasi UDP dan mengirimkan data mereka melalui server.
TURN server dirancang sedemikian rupa sehingga pemrakarsa koneksi memiliki lebih banyak fitur daripada sisi lainnya. Ini mengarah ke efek yang menarik ketika panggilan melalui server MENGHIDUPKAN berhasil atau tidak berhasil, tergantung pada siapa yang memanggil siapa (ingat semua penerjemah Skype - note).
Debugging
Jadi, Anda membaca hingga paragraf ini. Kami senang dengan penerjemah dan ingat bahwa artikelnya adalah tentang debugging WebRTC. Tetapi semua hal di atas adalah minimum yang diperlukan, yang tanpanya Anda bahkan tidak bisa memulai. Tetapi jika Anda memulai, dan Anda tidak memiliki keberuntungan yang tidak manusiawi, maka itu akan hancur.
Ini akan pecah dengan berbagai cara. Yang pertama adalah kurangnya konektivitas. Anda melewati pengaturan STUN dan TURN server ke kedua WebRTC, membantu mereka bertukar penawaran, menjawab, dan kandidat ICE, tetapi tidak ada video atau suara. Di mana untuk memulai? Dengan masalah pemutaran lokal.
WebRTC debugging lokal
Seperti yang saya tulis di atas, pekerjaan utama WebRTC terjadi di sisi browser. STUN dan TURN server sangat sederhana, sehingga sebagian besar masalah terjadi pada kode JavaScript Anda, yang berjalan di dua browser. Sedih tapi benar. Di sisi lain, jika hal yang paling menarik terjadi secara lokal di peramban, maka Anda memiliki banyak peluang untuk melakukan debug!
Hal pertama yang harus diperiksa adalah pensinyalan Anda. Ini adalah kode Anda yang mentransmisikan konfigurasi audio dengan video (penawaran, jawaban) dan informasi tentang pengaturan jaringan (kandidat es) di antara browser. Anda perlu memeriksa paket mana yang dikirim, yang menerima dan mengirim WebRTC:
- sisi lain koneksi menerima tawaran? Sudahkah inisiator koneksi menerima tanggapan? Koneksi tidak akan terjadi tanpa pertukaran fasilitas minimal ini;
- Apakah WebRTC di kedua ujung koneksi memberikan Anda paket dengan kandidat ICE? Apakah Anda menukar paket-paket ini dan meneruskannya kembali ke sisi yang berlawanan menggunakan addIceCandidate ?
- jika semuanya berjalan baik dengan pertukaran paket, apakah event handler onaddstream dipanggil dan apakah Anda menginstal objek yang dihasilkan dalam elemen HTML untuk memutar video (atau audio)?
Jika pertukaran paket tidak mencurigakan, maka Anda dapat mempelajari isi sesi ini.
Protokol deskripsi sesi
Paket penawaran, Jawaban, dan kandidat ICE dibuat oleh WebRTC dalam format teks SDP. Pada pandangan pertama, isi paket terlihat menakutkan, tetapi dengan sedikit persiapan Anda bisa mendapatkan banyak manfaat darinya selama debugging. Wikipedia menggambarkan SDP dengan cukup baik, tetapi saya menemukan
deskripsi yang lebih baik untuk Anda.
Bidang yang paling penting dalam paket ICE SDP kandidat adalah
typ . Untuk WebRTC, bidang dapat memiliki salah satu dari tiga nilai:
- inang ketik;
- ketik srflx;
- ketik relay.
ketik host
Tipe
host menentukan kandidat ICE untuk koneksi area lokal (WebRTC menyebutkan beberapa kandidat dengan harapan membangun koneksi, tidak diketahui sebelumnya mana yang akan keluar - perhatikan oleh penerjemah). Koneksi semacam itu tidak memerlukan STUN atau TURN server, karena perangkat di jaringan lokal seringkali dapat membuat koneksi jaringan secara langsung. Saat melakukan debug dari jaringan lokal, Anda hanya perlu memeriksa dan men-debug pengiriman paket
host dan memastikan bahwa perangkat dapat saling mengirim paket UDP. Meskipun ada pengecualian, dalam praktiknya saya telah melihat konfigurasi jaringan di mana browser membutuhkan server TURN untuk menghubungkan ... ke dirinya sendiri.
ketik srflx
Kombinasi huruf "srflx" adalah singkatan dari "Server Reflexive" dan menandai kandidat koneksi menggunakan alamat IP eksternal, di mana server STUN cukup untuk koneksi (menggunakan teknologi penetrasi NAT, yang berhasil dalam sekitar 80% kasus, catat penerjemah).
ketik relay
"Relay" menandai koneksi melalui server TURN, yang hampir selalu berhasil. Penting untuk diingat bahwa WebRTC tidak diharuskan untuk membuat tepat tiga paket berbeda dengan bidang "typ"; bagaimana kandidat dipilih tergantung pada implementasi WebRTC dalam versi browser tertentu.
Menguji konektivitas perangkat
Google menawarkan
aplikasi web khusus untuk menguji koneksi WebRTC pada perangkat Anda. Buka halaman, klik tombol "mulai" dan kode JavaScript akan mencoba membuat koneksi ke server Google menggunakan pensinyalan, server STUN dan TURN Google.
WebRTC Internal
Anda memeriksa semua paket, memeriksa kodenya, semuanya terlihat benar, tetapi tidak berhasil? Untuk kasus seperti itu, Google telah menyediakan browser Chrome dengan bagian khusus yang menunjukkan internal WebRTC selama penyiapan koneksi dan beberapa grafik yang indah jika koneksi berhasil. Untuk menggunakan, buka tautan teknis khusus di browser:
chrome://webrtc-internals
Jika Anda sudah memiliki aplikasi menggunakan WebRTC terbuka, Anda akan segera melihat banyak data teknis. Jika tidak, buka saja tab lain dan ada sesuatu di dalamnya yang menggunakan WebRTC. Tab menampilkan semua panggilan ke objek
RTCPeerConnection dan memungkinkan Anda untuk melihat secara real time bagaimana koneksi dibuat.
Pengaturan ICE
Di bagian atas halaman adalah string ICE yang digunakan untuk menginisialisasi koneksi. Jika kesalahan dibuat selama pembentukannya, ini akan segera terlihat (oleh "ICE line" penulis merujuk ke konfigurasi objek RTCPeerConnection dengan daftar STUN dan MENGHIDUPKAN server (objek 'iceServers') - catatan oleh penerjemah). Mungkin tidak ada daftar server? Anda harus mengonfigurasi objek RTCPeerConnection sebelum melakukan panggilan pertama ke
createOffer atau
createAnswer .
Acara RTCPeerConnection
Bagian internal berikutnya menunjukkan panggilan ke metode
RTCPeerConnection dan peristiwa yang diterima dari objek dalam urutan kronologis. Kesalahan disorot dengan hati-hati dalam warna merah. Harap perhatikan bahwa
addIceCandidateFailed merah seringkali bukan merupakan tanda kesalahan dan koneksi dapat terbentuk secara normal. Jika koneksi berhasil, acara terakhir dalam daftar akan menjadi
iceconnectionstatechange event dengan nilai
selesai .
Bagian 'statistik'
Bagian selanjutnya relevan ketika koneksi berhasil dibuat. Ini berisi statistik dari data yang dikirim dan penundaan jaringan. Dua opsi yang paling menarik adalah:
ssrc dan
bweforvideo .
- ssrc , "Stream Source", menandai setiap trek audio dan video Anda. Menampilkan statistik data dan parameter yang dikirimkan seperti waktu pulang pergi ;
- bweforvideo , Perkiraan BandWidth, menampilkan lebar saluran jaringan yang digunakan.
Fungsi GetStats
Seringkali Anda tidak akan dapat mengakses halaman internal. Misalnya, ketika terjadi masalah dengan pengguna Anda. Dalam hal ini, Anda bisa mendapatkan data yang sama dengan yang ditunjukkan halaman internal dengan memanggil metode
getStats pada objek
RTCPeerConnection . Metode ini mengatur fungsi panggilan balik yang akan dipanggil WebRTC setiap kali sesuatu yang menarik terjadi. Fungsi yang dipanggil mendapatkan objek dengan bidang yang ditampilkan halaman internal:
rtcPeerConnection.getStats(function(stats) { document.getElementById("lostpackets").innerText = stats.packetsLost; });
Alat lain yang bermanfaat adalah event
oniceconnectionstatechange objek
RTCPeerConnection . Handler event akan menerima informasi progres koneksi. Opsi yang memungkinkan:
- baru : WebRTC mengharapkan kandidat dari sisi kedua koneksi, yang harus ditambahkan menggunakan metode addIceCandidate ;
- memeriksa : WebRTC menerima kandidat dari sisi kedua koneksi, membandingkannya dengan yang lokal dan beralih pada opsi;
- terhubung : sepasang kandidat yang cocok dipilih dan koneksi dibuat. Patut dicatat bahwa setelah ini, kandidat dapat terus datang, sesuai dengan protokol Trickle ICE;
- selesai : semua kandidat diterima dan koneksi dibuat.
- terputus : koneksi terputus . Pada saluran yang tidak stabil, WebRTC dapat terhubung kembali, kami memantau flag yang terhubung ;
- ditutup : koneksi terputus dan WebRTC tidak lagi berfungsi dengannya.
Jika koneksi berakhir dalam keadaan
gagal , maka kita dapat memeriksa kandidat yang diterima di kedua sisi dan memahami mengapa koneksi gagal. Misalnya, jika satu sisi menyediakan
host dan
kandidat srflx , sisi lain
host dan
relay , tetapi perangkat berada di jaringan yang berbeda.
Kotak hitam bukan video
Seringkali ada situasi ketika koneksi dibuat, suara ditransmisikan, tetapi bukannya video, satu atau kedua peserta memiliki persegi panjang hitam. Paling sering ini terjadi jika Anda menetapkan objek video yang diterima ke elemen HTML sebelum koneksi transisi ke keadaan
selesai .
Cara menyodok tongkat di luar
Selain objek
RTCPeerConnection itu sendiri dan internal yang ditampilkan oleh browser, Anda dapat menggunakan alat analisis paket jaringan seperti Wireshark. Alat-alat ini dapat menampilkan paket-paket protokol WebRTC yang digunakan. Misalnya, Wireshark akan menunjukkan kepada Anda konten paket STUN di jendela utama, dan Anda dapat memfilternya dengan mengetikkan kata kunci “setrum” di bidang filter:
Apa yang harus dilihat di respons server? Jika Anda hanya melihat jawaban dengan tipe
Binding , ini berarti hanya STUN (pembicaraan IP eksternal) yang didukung, dan WebRTC hanya dapat menawarkan kandidat
srflx . Jika jawaban berisi paket TURN khusus
Alokasi dan
CreatePermission , maka WebRTC akan memiliki kesempatan untuk mencoba menghubungkan melalui server proxy. Penganalisa paket menandai
Alokasi yang berhasil dan tidak berhasil. Jika tidak ada satu yang berhasil, maka kemungkinan besar parameter akses yang salah ke server TURN (yang hampir selalu dilindungi dengan nama pengguna dan kata sandi - catatan penerjemah) dilewatkan.
Jika ada paket
Respons Keberhasilan CreatePermission di log, maka kita dapat mengasumsikan bahwa semuanya baik-baik saja dengan konfigurasi STUN dan TURN. Dan jika ada juga paket
ChannelBind , maka dimungkinkan untuk membuat koneksi ke server MENGHIDUPKAN dengan kecepatan tinggi.
Masalah Seluler
Dalam praktik saya, banyak solusi WebRTC yang membuat koneksi WiFi tidak dapat terhubung melalui 3G / 4G. Aplikasi yang diluncurkan pada perangkat seluler lebih sulit untuk di-debug: kami tidak memiliki penganalisa paket sederhana seperti Wireshark, dan Safari tidak dapat menampilkan internal WebRTC. Logika menunjukkan bahwa jika aplikasi berfungsi dengan baik melalui WiFi, maka masalahnya bukan pada aplikasi itu sendiri, tetapi dalam komunikasi seluler. Bagaimana cara debug? Ambil laptop dan sambungkan
dongle 3G ke dalamnya. Jadi Anda memiliki penganalisa paket dan log yang mudah digunakan yang dapat Anda temukan akar semua masalah dalam waktu yang wajar.
Kesimpulan
Debugging WebRTC tidak mudah, tetapi jika Anda mencari dengan baik di Internet, Anda dapat menemukan banyak artikel dan contoh. Jika Anda bekerja di bidang komunikasi waktu nyata, maka saya sarankan Anda membaca spesifikasi RFC untuk
STUN ,
MENGHIDUPKAN protokol dan teknologi
WebRTC . Dokumennya besar, tetapi informasi yang terkandung di dalamnya membantu membuat keputusan yang andal dan menjawab pertanyaan "mengapa tidak berdering".