Dari sudut pandang pengguna, layanan panggilan terlihat cukup sederhana: Anda pergi ke halaman ke pengguna lain, Anda menelepon, dia mengangkat telepon, Anda berbicara dengannya. Di luar sepertinya semuanya sederhana, tetapi sedikit yang tahu bagaimana membuat layanan seperti itu. Namun Alexander Tobol (
alatobol ) tidak hanya tahu, tetapi juga rela berbagi pengalamannya.

Selanjutnya versi teks laporan tentang HighLoad ++ Siberia, dari mana Anda akan belajar:
- bagaimana layanan panggilan video bekerja di bawah tenda;
- betapa indahnya menembus NAT - ini akan menarik bagi spesialis game yang membutuhkan koneksi peer-to-peer;
- bagaimana WebRTC bekerja, protokol apa yang termasuk di dalamnya;
- bagaimana saya bisa menyetel WebRTC melalui BigData.
Tentang pembicara: Alexander Tobol memimpin pengembangan platform Video dan Tape di ok.ru.
Riwayat panggilan video
Perangkat pertama untuk panggilan video muncul pada tahun 1960, itu disebut picherphone, menggunakan jaringan khusus dan sangat mahal. Pada tahun 2006, Skype menambahkan panggilan video ke aplikasinya. Pada 2010, Flash mendukung protokol RTMFP, dan kami di Odnoklassniki meluncurkan panggilan video Flash. Pada 2016, Chrome berhenti mendukung Flash, dan pada Agustus 2017 kami memulai kembali panggilan dengan teknologi baru, yang akan saya bicarakan hari ini. Setelah menyelesaikan layanan, selama enam bulan kami menerima peningkatan yang signifikan dalam panggilan yang berhasil diselesaikan. Baru-baru ini, kami juga memiliki topeng dalam panggilan.

Arsitektur dan TK
Karena kami bekerja di jejaring sosial, kami tidak memiliki tugas teknis, dan kami tidak tahu apa itu TK. Biasanya seluruh ide cocok pada satu halaman dan terlihat seperti ini.

Pengguna ingin memanggil pengguna lain menggunakan web atau aplikasi iOS / Android. Pengguna lain mungkin memiliki beberapa perangkat. Panggilan datang ke semua perangkat, pengguna mengangkat telepon pada salah satu dari mereka, mereka berbicara. Semuanya sederhana.
Spesifikasi teknis
Untuk membuat layanan panggilan yang berkualitas, kita perlu memahami karakteristik apa yang ingin kita lacak. Kami memutuskan untuk memulai dengan mencari apa yang paling mengganggu pengguna.
Pengguna pasti kesal jika dia mengangkat telepon dan dipaksa untuk menunggu sampai sambungan dibuat.

Pengguna terganggu jika kualitas panggilan buruk - ada yang terganggu, video tersebar, suaranya menggelegak.

Tetapi sebagian besar dari semua pengguna terganggu oleh keterlambatan panggilan. Latensi adalah salah satu karakteristik penting panggilan. Dengan latensi dalam percakapan dalam urutan 5 detik, sama sekali tidak mungkin untuk melakukan dialog.

Kami telah menentukan sendiri karakteristik yang dapat diterima:
- Mulai - kami memutuskan bahwa baik untuk memulai panggilan dalam sedetik. Yaitu menghubungkan setelah pengguna menjawab, harus tidak lebih dari 1 detik.
- Kualitas adalah indikator yang sangat subyektif. Anda dapat mengukur, misalnya, rasio signal-to-noise (SNR), tetapi masih ada bingkai yang hilang dan artefak lainnya. Kami mengukur kualitas secara subyektif dan kemudian mengevaluasi kebahagiaan pengguna.
- Latensi harus kurang dari 0,5 detik. Jika Latency lebih dari 0,5 detik, maka Anda sudah mendengar penundaan dan mulai saling mengganggu.

Polycom adalah sistem konferensi yang dipasang di kantor kami. Kami memiliki latensi rata-rata polycom dalam urutan 1,3 detik. Dengan penundaan seperti itu, Anda tidak selalu saling memahami. Jika penundaan meningkat menjadi 2 detik, maka dialog tidak akan mungkin.

Karena kami telah meluncurkan platform, kami memperkirakan bahwa kami akan memiliki sejuta panggilan per hari. Ini seribu panggilan secara paralel. Jika semua panggilan diluncurkan melalui server, akan ada seribu panggilan megabit per panggilan. Ini hanya 1 gigabit / detik satu server besi sudah cukup.
Internet vs TTX
Apa yang bisa mencegah Anda mencapai fitur-fitur keren seperti itu? Internet!

Di Internet, ada hal-hal seperti round-trip time (RTT), yang tidak bisa diatasi, ada bandwidth variabel, ada NAT.
Sebelumnya, kami mengukur kecepatan transmisi di jaringan pengguna kami.

Kami memecahnya berdasarkan jenis koneksi, melihat RTT rata-rata, kehilangan paket, kecepatan, dan memutuskan bahwa kami akan menguji panggilan pada nilai rata-rata dari masing-masing jaringan ini.

Ada masalah lain di Internet:
- Paket hilang - kami mengukur 0,6% kehilangan paket acak (kami tidak memperhitungkan kehilangan paket kemacetan akun dengan jumlah paket yang berlebihan).
- Pengubahan urutan - Anda mengirim paket dalam urutan yang sama, dan jaringan mengurutkannya kembali.
- Jitter - mengirim aliran video atau audio pada interval tertentu, dan paket-paket berkumpul di sisi klien dalam bundel, misalnya, karena buffering pada perangkat jaringan.
- NAT - ternyata lebih dari 97% pengguna berada di belakang NAT. Kami akan berbicara tentang mengapa, apa dan bagaimana.

Pertimbangkan pengaturan jaringan yang tercantum di atas dengan contoh sederhana.
Saya membuka situs web Universitas Negeri Novosibirsk dari kantor saya dan mendapat ping yang aneh.

Jitter rata-rata dalam contoh ini adalah 30 ms, yaitu, interval rata-rata antara waktu ping yang berdekatan adalah sekitar 30 ms, dan ping rata-rata adalah 105 ms.
Yang penting dalam panggilan, mengapa kita berjuang untuk p2p?

Jelas, jika kami berhasil membuat koneksi p2p antara pengguna kami yang mencoba berbicara satu sama lain di St. Petersburg, dan tidak melalui server yang berlokasi di Novosibirsk, kami akan menghemat sekitar 100 ms pulang pergi dan lalu lintas ke layanan ini.
Karena itu, sebagian besar artikel dikhususkan untuk bagaimana membuat p2p yang baik.
Sejarah atau warisan
Seperti yang saya katakan, kami telah memiliki layanan panggilan sejak 2010, dan sekarang kami telah memulainya kembali.

Pada 2006, ketika Skype mulai, Flash membeli Amicima, yang menghasilkan RTMFP. Flash sudah memiliki RTMP, yang pada prinsipnya dapat digunakan untuk panggilan, dan itu sering digunakan untuk streaming. Flash kemudian membuka spesifikasi RTMP. Saya heran mengapa mereka membutuhkan RTMFP? Pada 2010, kami menggunakan RTMFP.
Bandingkan persyaratan untuk protokol panggilan dan protokol streaming nyata dan lihat di mana perbatasan ini.
RTMP lebih merupakan protokol streaming video. Menggunakan TCP, memiliki penundaan kumulatif. Jika Anda memiliki koneksi internet yang baik, panggilan ke RTMP akan berfungsi.
Protokol RTMFP , meskipun berbeda hanya dalam satu huruf, adalah protokol UDP. Ini bebas dari masalah buffering - yang ada di TCP; Ini dihilangkan dari pemblokiran head-of-line - ini adalah ketika Anda kehilangan satu paket, dan TCP tidak mengembalikan paket-paket berikut sampai tiba waktunya untuk mengirim ulang paket yang hilang. RTMFP mampu menangani NAT dan mengalami perubahan dalam alamat IP klien. Karena itu, kami meluncurkan web di RTMFP pada 2010.

Kemudian hanya pada tahun 2011 muncul konsep awal WebRTC, yang belum sepenuhnya operasional. Pada 2012, kami mulai mendukung panggilan di iOS / Android, kemudian sesuatu yang lain terjadi, dan pada 2016 Chrome berhenti mendukung Flash. Kami harus melakukan sesuatu.

Kami melihat semua protokol VoIP: seperti biasa, untuk melakukan sesuatu, kami mulai dengan melihat pesaing.
Pesaing atau mulai dari mana
Kami memilih pesaing paling populer: Skype, WhatsApp, Google Duo (mirip dengan Hangouts) dan ICQ.
Untuk mulai dengan, kami mengukur penundaan.

Itu mudah dilakukan. Di atas adalah foto di mana:
- Stopwatch (lihat telepon di kiri atas), yang menunjukkan waktu (03:08).
- Telepon terdekat melakukan panggilan dan mengambil telepon pertama sebagai video. Dari saat gambar masuk ke kamera ponsel, dan Anda melihatnya, butuh sekitar 100 ms.
- Panggilan ke telepon lain (putih) dan sekali lagi. Di sini penundaannya sekitar 310 ms dengan Google Duo.
Saya belum akan mengungkapkan semua kartu, tetapi kami memastikan bahwa perangkat ini tidak dapat membuat koneksi P2P. Tentu saja, pengukuran dilakukan di jaringan yang berbeda, dan ini hanyalah sebuah contoh.

Skype masih sedikit menyela. Ternyata dengan Skype, jika gagal menghubungkan p2p, penundaannya adalah 1,1 detik.
Lingkungan pengujian kami rumit. Kami menguji dalam kondisi yang berbeda (EDGE, 3G, LTE, WiFi), memperhitungkan bahwa salurannya asimetris, dan saya memberikan nilai rata-rata dari semua pengukuran.

Untuk memperkirakan konsumsi baterai, beban prosesor, dan yang lainnya, kami memutuskan bahwa Anda cukup mengukur suhu ponsel dengan pirometer dan berasumsi bahwa ini adalah beban rata-rata pada GPU ponsel per prosesor, baterai. Pada prinsipnya, sangat tidak menyenangkan untuk membawa telepon panas ke telinga Anda, dan bahkan memegangnya di tangan Anda. Tampaknya bagi pengguna bahwa sekarang aplikasi akan menghabiskan seluruh baterainya.

Hasilnya adalah:
- Yang paling lambat dalam penundaan itu adalah ICQ dan Skype, dan yang tercepat - Telegram. Ini bukan perbandingan yang sepenuhnya benar, karena Telegram tidak memiliki panggilan video, tetapi mereka memiliki latensi minimal dalam audio. WhatsApp (sekitar 200 ms) dan Hangouts - 390 ms berfungsi dengan baik.
- Berdasarkan suhu, Telegram makan paling sedikit tanpa video, dan Skype paling banyak.
- Dalam hal waktu respons , Telegram membangun koneksi untuk waktu yang lama, dan WhatsApp dan Google Duo tercepat.
Hebat, kami mendapat beberapa metrik!

Kami menguji kualitas video dan suara di jaringan yang berbeda, dengan tetesan yang berbeda dan yang lainnya. Sebagai hasilnya, kami sampai pada kesimpulan bahwa
video kualitas tertinggi adalah di Google Duo, dan suara ada di Skype , tetapi ini ada di jaringan "buruk" ketika sudah ada distorsi. Secara umum, setiap orang bekerja kurang lebih biasa-biasa saja. WhatsApp memiliki gambar yang paling kabur.
Mari kita lihat apa yang sudah diimplementasikan.

Skype memiliki protokol miliknya sendiri, dan semua orang menggunakan modifikasi WebRTC, atau umumnya WebRTC secara langsung. Hangouts, Google Duo, WhatsApp, Facebook Messenger dapat bekerja dengan web, dan mereka semua memiliki WebRTC di bawah tenda. Mereka semua sangat berbeda, dengan karakteristik yang berbeda, dan mereka semua memiliki satu WebRTC! Jadi, Anda harus bisa memasaknya dengan benar. Plus ada Telegram, yang beberapa bagian WebRTC bertanggung jawab untuk bagian audio, ada ICQ, yang bercabang dengan WebRTC untuk waktu yang lama dan terus mengembangkan caranya sendiri.
WebRTC Arsitektur

WebRTC menyiratkan adanya server pensinyalan, perantara antara klien, yang digunakan untuk bertukar pesan selama pembuatan koneksi p2p di antara mereka. Setelah membuat koneksi langsung, klien mulai saling bertukar data media satu sama lain.
WebRTC Demo
Mari kita mulai dengan demo sederhana. Ada 5 langkah sederhana untuk membuat koneksi WebRTC.
Dikatakan sebagai berikut:
- Ambil video dan buat koneksi peer, transfer semacam iceServers (tidak segera jelas apa itu).
- Buat penawaran SDP dan kirimkan ke signaling, dan signalling WebRTC tidak akan menerapkan untuk Anda dengan cara apa pun.
- Maka Anda perlu membuat pembungkus untuk yang berasal dari pensinyalan, dan ini juga bukan bagian dari WebRTC.
- Selanjutnya tukar beberapa kandidat.
- Akhirnya dapatkan streaming video jarak jauh.
Mari cari tahu apa yang terjadi di sana dan apa yang perlu kita terapkan sendiri.

Kami melihat gambar dari bawah ke atas. Ada perpustakaan WebRTC yang sudah ada di dalam browser, didukung oleh Chrome, Firefox, dll. Anda dapat membangunnya di bawah Android / iOS dan berkomunikasi dengannya melalui API dan SDP (Session Description Protocol), yang menjelaskan sesi itu sendiri. Di bawah ini saya akan memberi tahu Anda apa yang termasuk di dalamnya. Untuk menggunakan perpustakaan ini di aplikasi Anda, Anda harus membuat koneksi antara pelanggan melalui pensinyalan. Signaling juga merupakan layanan Anda yang harus Anda tulis sendiri, WebRTC tidak menyediakannya.
Selanjutnya dalam artikel ini kita akan membahas jaringan secara berurutan, kemudian video / audio, dan pada akhirnya kita akan menulis pensinyalan kita.
Jaringan WebRTC atau p2p (sebenarnya c2s2c)
Menyiapkan koneksi P2P tampaknya cukup sederhana.

Kami memiliki Alice dan Bob yang ingin membuat koneksi P2P. Mereka mengambil alamat IP mereka, mereka memiliki server pensinyalan yang keduanya terhubung, dan melalui mana mereka dapat bertukar alamat ini. Mereka bertukar alamat, dan oh! Mereka memiliki alamat yang sama, ada yang salah!

Bahkan, kedua pengguna kemungkinan besar duduk di belakang router Wi-Fi dan ini adalah alamat IP abu-abu lokal mereka. Router menyediakan mereka dengan fitur seperti Terjemahan Alamat Jaringan (NAT). Bagaimana cara kerjanya?

Anda memiliki subnet abu-abu dan alamat IP eksternal. Anda mengirim paket ke Internet dari alamat abu-abu Anda, NAT mengganti alamat abu-abu Anda dengan warna putih dan mengingat pemetaan: dari mana port itu dikirim, ke pengguna mana dan port mana yang cocok. Ketika paket kembali tiba, itu diselesaikan dengan pemetaan ini dan mengirimkannya ke pengirim. Semuanya sederhana.
Di bawah ini adalah ilustrasi bagaimana tampilannya di tempat saya.

Ini adalah alamat IP internal saya dan alamat router (omong-omong, juga abu-abu). Jika Anda melacak dan melihat rute, kita akan melihat router Wi-Fi saya: paket alamat penyedia abu-abu dan IP putih eksternal. Jadi, pada kenyataannya, saya akan memiliki dua NAT: satu di mana saya berada di Wi-Fi, dan yang lain dari penyedia, kecuali, tentu saja, saya membeli sendiri alamat IP eksternal yang khusus.
NAT sangat populer karena:- banyak IPv4 masih hilang, dan tidak ada cukup alamat;
- NAT tampaknya melindungi jaringan;
- ini adalah fungsi standar router: terhubung ke Wi-Fi, ada NAT di sana, itu berfungsi.
Oleh karena itu, hanya 3% pengguna yang duduk dengan IP eksternal, sedangkan sisanya melalui NAT.
NAT memungkinkan Anda untuk dengan aman pergi ke alamat putih mana pun. Tetapi jika Anda tidak pergi ke mana pun, maka tidak ada yang bisa mendatangi Anda.

Untuk membuat koneksi P2P adalah masalah. Faktanya, Alice dan Bob tidak dapat saling mengirim paket jika keduanya berada di belakang NAT.
WebRTC memiliki
protokol STUN untuk menyelesaikan masalah ini. Diusulkan untuk menggunakan server STUN. Kemudian Alice terhubung ke server STUN, mendapatkan alamat IP-nya, mengirimkannya ke Bob melalui pensinyalan. Bob juga mendapatkan alamat IP-nya dan mengirimkannya ke Alice. Mereka mengirim paket ke satu sama lain dan dengan demikian menerobos NAT.
Pertanyaan : Alice memiliki porta tertentu yang terbuka, NAT / Firewall telah diterobos ke porta ini, dan Bob terbuka. Mereka tahu alamat masing-masing. Alice mencoba mengirim paket ke Bob, dia mengirim paket ke Alice. Apakah Anda pikir mereka dapat berbicara atau tidak?
Bahkan, Anda benar dalam hal apa pun, hasilnya tergantung pada jenis pasangan NAT yang dimiliki pengguna.

Terjemahan alamat jaringan
Ada 4 jenis NAT:
- NAT kerucut penuh;
- NAT kerucut terbatas;
- Port cone NAT yang dibatasi;
- NAT simetris
Dalam versi dasar, Alice mengirimkan paket ke server STUN, ia membuka beberapa port. Bob entah bagaimana mengetahui tentang portalnya dan mengirim paket balasan. Jika ini adalah
Full cone NAT - yang termudah yang hanya memetakan port eksternal ke port internal, maka Bob akan dapat segera mengirim paket Alice, membuat koneksi, dan mereka akan berbicara.

Di bawah ini adalah skema interaksi: Alice dari beberapa port mengirim paket ke port STUN, STUN menjawabnya dengan alamat eksternalnya. STUN dapat merespons dari alamat mana pun, jika itu adalah NAT kerucut penuh, itu masih akan menembus NAT, dan Bob dapat menanggapi alamat yang sama.

Dalam kasus
NAT kerucut Terbatas, hal-hal sedikit lebih rumit. Ia mengingat tidak hanya port tempat Anda perlu memetakan ke alamat internal, tetapi juga alamat eksternal yang Anda tuju. Yaitu, jika Anda telah membuat koneksi hanya ke server IP STUN, maka tidak ada orang lain di jaringan yang dapat menjawab Anda, dan kemudian paket Bob tidak akan menjangkau.

Bagaimana mengatasi masalah ini? Dalam skema sederhana (lihat ilustrasi di bawah) seperti ini: Alice mengirim paket ke STUN, ia menjawabnya dengan IP-nya. STUN dapat meresponsnya dari port mana pun asalkan itu Dibatasi kerucut NAT. Bob tidak dapat menjawab Alice karena dia memiliki alamat yang berbeda. Alice merespons dengan sebuah paket, mengetahui alamat IP Bob. Dia membuka NAT untuk Bob, Bob menjawabnya. Hore, mereka berbicara.

Opsi yang sedikit lebih rumit adalah
Port cone NAT . Semua sama, hanya STUN yang harus merespons dengan tepat dari port yang diaksesnya. Semuanya akan bekerja juga.
Yang paling berbahaya adalah
Symmetric NAT .

Pada awalnya, semuanya bekerja dengan cara yang persis sama - Alice mengirim paket ke server STUN, ia merespons dari port yang sama. Bob tidak bisa menjawab Alice, tetapi ia mengirim paket ke Bob. Dan di sini, terlepas dari kenyataan bahwa Alice mengirim paket ke port 4444, pemetaan mengalokasikan port baru untuknya. Symmetric NAT berbeda dalam hal bahwa ketika setiap koneksi baru dibuat, setiap kali mengeluarkan port baru pada router. Dengan demikian, Bob berdetak di pelabuhan tempat Alice pergi ke STUN, dan mereka tidak dapat terhubung.
Di arah yang berlawanan, jika Bob memiliki alamat IP terbuka, Alice mungkin datang kepadanya dan mereka akan membuat koneksi.
Semua opsi dikumpulkan dalam satu tabel di bawah ini.

Ini menunjukkan bahwa hampir semuanya mungkin kecuali ketika kami mencoba untuk membuat koneksi melalui Symmetric NAT dengan Port cone NAT atau NAT Symmetric di ujung lainnya.

Seperti yang kami ketahui, p2p sangat berharga bagi kami dalam hal latensi, tetapi jika itu tidak mungkin untuk menginstalnya, maka WebRTC menawarkan kepada kami server TURN. Ketika kami menyadari bahwa p2p tidak akan diinstal, kami dapat terhubung ke TURN, yang akan mem-proxy semua lalu lintas. Namun, pada saat yang sama Anda akan membayar untuk lalu lintas, dan pengguna mungkin memiliki beberapa penundaan tambahan.
Berlatih
Google memiliki server STUN gratis. Anda bisa meletakkannya di perpustakaan, itu akan berhasil.
TURN server memiliki kredensial (login dan kata sandi). Kemungkinan besar, Anda harus menaikkan sendiri, agak sulit ditemukan gratis.
Contoh server STUN gratis dari Google:
- stun: stun.l.google.com: 19302
- stun: stun1.l.google.com: 19302
- stun: stun2.l.google.com: 19302
- stun: stun3.l.google.com: 19302
Dan server MENGHIDUPKAN gratis dengan kata sandi: url: 'turn: 192.158.29.39: 3478? Transport = udp', kredensial: 'JZEOEt2V3Qb0y27GRntt2u2PAYA =', nama pengguna: '28224511: 1379330808 β².
Kami menggunakan
coturn .

Akibatnya, 34% lalu lintas melewati koneksi p2p, yang lainnya diproksi melalui server TURN.
Apa lagi yang menarik dalam protokol STUN?
STUN memungkinkan Anda untuk menentukan jenis NAT.
Slide linkSaat mengirim paket, Anda dapat menunjukkan bahwa Anda ingin menerima respons dari port yang sama atau meminta STUN untuk merespons dari port yang berbeda, dari IP yang berbeda, atau bahkan dari IP dan port yang berbeda. Jadi,
untuk 4 pertanyaan ke server STUN, Anda dapat menentukan jenis NAT .

Kami menghitung jenis-jenis NAT dan kami mendapatkan bahwa hampir semua pengguna memiliki NAT Simetris atau NAT yang dibatasi kerucut Port. Oleh karena itu, ternyata hanya sepertiga pengguna yang dapat membuat koneksi p2p.
Anda mungkin bertanya mengapa saya memberi tahu Anda semua ini jika Anda bisa mengambil STUN dari Google, memasukkannya ke WebRTC, dan sepertinya semuanya akan berhasil.
Karena Anda sebenarnya dapat menentukan jenis NAT sendiri.

Ini adalah
tautan ke aplikasi Java yang tidak melakukan apa pun yang rumit: itu hanya ping port yang berbeda dan server STUN berbeda, dan melihat port mana yang dilihatnya pada akhirnya. Jika Anda memiliki Open Full cone NAT, maka STUN server akan memiliki port yang sama. Dengan NAT kerucut Terbatas, Anda akan memiliki port yang berbeda untuk setiap permintaan STUN.

Dengan Symmetric NAT, ternyata begini di kantorku. Ada port yang sama sekali berbeda.
Tetapi kadang-kadang ada pola yang menarik bahwa untuk setiap koneksi, nomor port bertambah satu.

Yaitu, banyak NAT yang dikonfigurasi sehingga mereka menambah atau mengurangi port dengan konstanta. Konstanta ini dapat ditemukan dan dengan demikian menerobos NAT Simetris.

Jadi kami menerobos NAT - kami pergi ke satu server STUN, ke yang lain, melihat perbedaannya, membandingkan dan mencoba lagi untuk memberikan port kami dengan kenaikan atau penurunan ini. Artinya, Alice mencoba memberikan Bob portalnya, sudah disesuaikan dengan konstanta, tahu bahwa lain kali itu akan terjadi.

Jadi kami berhasil mengelas
12% peer-to-peer lainnya .
Bahkan, kadang-kadang router eksternal dengan IP yang sama berperilaku sama. Oleh karena itu, jika Anda mengumpulkan statistik dan jika Symmetric NAT adalah fitur dari penyedia, dan bukan fitur dari router Wi-Fi pengguna, maka delta dapat diprediksi, segera kirim ke pengguna sehingga ia menggunakannya dan tidak menghabiskan terlalu banyak waktu untuk menentukannya.
Relay CDN atau apa yang harus dilakukan jika Anda tidak dapat membuat koneksi P2P
Jika kita masih menggunakan TURN server dan bekerja tidak di p2p, tetapi dalam mode real, melewati semua lalu lintas melalui server, kita masih bisa menambahkan CDN. Kecuali, tentu saja, Anda memiliki taman bermain. Kami memiliki situs CDN kami sendiri, jadi bagi kami itu cukup sederhana. Tapi itu perlu untuk menentukan di mana lebih baik untuk mengirim seseorang: ke situs CDN atau, katakanlah, ke saluran ke Moskow. Ini bukan tugas yang sangat sepele, jadi kami melakukan ini:
- Sengaja dikeluarkan untuk beberapa pengguna situs Moskow, beberapa - jarak jauh.
- Kami mengumpulkan statistik pada IP pengguna, pada server dan pada karakteristik jaringan.
- Dengan maxMind, kami mengelompokkan subnet, melihat statistik dan dapat memahami dengan IP pengguna mana yang memiliki server HIDUP terdekat untuk koneksi.

Ada CDN di Novosibirsk. Jika semuanya bekerja untuk Anda melalui Moskow, maka persentil RTT ke-99 adalah 1,3 detik. Melalui CDN, semuanya bekerja jauh lebih cepat (0,4 detik).
Apakah selalu lebih baik menggunakan koneksi P2P dan tidak menggunakan server? Contoh yang menarik adalah dua penyedia Krasnoyarsk Optibyte dan Mobra (nama mungkin telah berubah). Untuk beberapa alasan, koneksi di antara mereka pada p2p jauh lebih buruk daripada melalui MSK. Mungkin mereka tidak berteman satu sama lain.

Kami menganalisis semua kasus seperti itu, secara acak mengirim pengguna ke p2p atau melalui MSK, mengumpulkan statistik dan membuat prediksi. Kami tahu bahwa statistik perlu diperbarui, jadi untuk beberapa pengguna kami secara khusus membuat koneksi yang berbeda untuk memeriksa apakah ada sesuatu yang berubah di jaringan.
Kami mengukur karakteristik sederhana seperti waktu bundar, kehilangan paket, bandwidth - tetap mempelajari cara membandingkannya dengan benar.

Bagaimana memahami mana yang lebih baik: 2 Mbit / s Internet, 400 ms RTT dan paket Loss 5% atau 100 Kbit / s, keterlambatan 100 ms dan sedikit paket loss?
Tidak ada jawaban yang pasti, penilaian kualitas panggilan video sangat subjektif. Oleh karena itu, setelah panggilan berakhir, kami meminta pengguna untuk mengevaluasi kualitas tanda bintang dan mengatur konstanta sesuai dengan hasilnya. Ternyata, misalnya, RTT kurang dari 300 ms - tidak masalah lagi, bitrate lebih penting.
Peringkat pengguna yang lebih tinggi untuk Android dan iOS. Terlihat bahwa pengguna iOS lebih cenderung untuk menempatkan unit dan lebih sering lima. Saya tidak tahu mengapa, mungkin, spesifik dari platform. Tapi kami menarik konstanta di sepanjang mereka, sehingga kami memiliki, sepertinya bagi kami, bagus.
Kembali ke garis besar kami untuk artikel, kami masih mendiskusikan jaringan.
Seperti apa pengaturan sambungan itu?
Kami mengirim STUN dan MENGHIDUPKAN server ke PeerConnection (), koneksi dibuat. Alice mengetahui IP-nya, mengirimkannya ke pensinyalan; Bob belajar tentang IP Alice. Alice mendapat IP Bob. Mereka bertukar paket, mungkin menerobos NAT, mungkin mengatur TURN dan berkomunikasi.

Dalam 5 langkah membangun koneksi yang kita bahas sebelumnya, kami menemukan server, menemukan di mana mendapatkannya, dan bahwa kandidat ICE adalah alamat IP eksternal yang kami bertukar melalui pensinyalan. Alamat IP internal klien, jika mereka berada dalam jangkauan satu Wi-Fi, juga dapat dicoba untuk menerobos.
Mari beralih ke bagian video.
Video dan audio
WebRTC mendukung satu set codec video dan audio tertentu, tetapi Anda dapat menambahkan codec Anda sendiri di sana. Pada dasarnya didukung oleh
H.264 dan VP8 untuk video . VP8 adalah codec perangkat lunak, oleh karena itu ia menghabiskan banyak baterai. H.264 tidak tersedia di semua perangkat (biasanya asli), jadi prioritas default adalah pada VP8.
Di dalam SDP (Session Description Protocol), ada negosiasi codec: ketika satu klien mengirim daftar codec-nya, yang lain mengirimkan sendiri dengan prioritas, dan mereka menyetujui codec mana yang akan mereka gunakan untuk komunikasi. Jika diinginkan, Anda dapat mengubah prioritas codec VP8 dan H.264, dan karenanya, Anda dapat menghemat baterai pada beberapa perangkat, tempat 264 adalah perangkat asli. Berikut adalah
contoh bagaimana hal ini dapat dilakukan. Kami melakukan ini, tampaknya bagi kami bahwa pengguna tidak mengeluh tentang kualitas, tetapi pada saat yang sama daya baterai dikonsumsi jauh lebih sedikit.
Untuk audio, WebRTC memiliki
OPUS atau G711 , biasanya semua OPUS selalu berfungsi, tidak ada yang perlu dilakukan dengannya.
Di bawah ini adalah pengukuran suhu setelah 10 menit penggunaan.

Jelas bahwa kami menguji berbagai perangkat. Ini adalah contoh iPhone, dan di atasnya, aplikasi OK menggunakan baterai paling sedikit, karena suhu perangkat paling sedikit.
Hal kedua yang dapat Anda aktifkan jika menggunakan WebRTC adalah
mematikan video secara otomatis saat koneksi sangat buruk .

Jika Anda memiliki kurang dari 40 Kbps, video akan mati. Anda hanya perlu mencentang kotak saat membuat koneksi, nilai ambang batas dapat dikonfigurasi melalui antarmuka. Anda juga dapat mengatur minimum dan maksimum mulai bitrate saat ini.

Ini adalah hal yang sangat berguna. Jika ketika Anda membuat koneksi yang Anda ketahui sebelumnya berapa bitrate yang Anda harapkan, Anda dapat mentransfernya, panggilan akan dimulai darinya, dan Anda tidak perlu mengadaptasi bitrate tersebut. Plus, jika Anda tahu bahwa Anda sering memiliki packet loss atau drawdowns bandwidth pada saluran Anda, maka nilai maksimumnya juga dapat dibatasi.
WhatsApp bekerja dengan video yang sangat sabun, tetapi dengan penundaan kecil, karena secara agresif menekan bitrate dari atas.
Kami mengumpulkan statistik menggunakan MaxMind dan memetakannya.

Ini adalah perkiraan kualitas awal yang kami gunakan untuk panggilan di berbagai wilayah di Rusia.
Pemberian sinyal
Anda kemungkinan besar harus menulis bagian ini jika ingin melakukan panggilan. Ada segala macam jebakan. Ingat bagaimana tampilannya.

Ada aplikasi dengan pensinyalan yang menghubungkan dan bertukar dengan SDP, dan SDP di bawah ini adalah antarmuka ke WebRTC.
Seperti inilah bentuk pensinyalan sederhana:

Alice memanggil Bob. Ini menghubungkan, misalnya, melalui koneksi soket web. Bob menerima dorongan pada ponsel atau browsernya, atau dalam semacam koneksi terbuka, terhubung melalui soket web dan setelah itu ponsel mulai berdering di sakunya. Bob mengangkat telepon, Alice mengiriminya codec dan fitur WebRTC lain yang didukungnya. Bob menjawab hal yang sama, dan setelah itu mereka bertukar kandidat yang mereka lihat. Hore, telepon!
Semuanya terlihat cukup panjang. Pertama, sampai Anda membuat koneksi soket-web, sampai dorongan datang dan yang lainnya, telepon Bob tidak akan berdering di sakunya. Alice akan menunggu sepanjang waktu, berpikir di mana Bob berada, mengapa dia tidak mengangkat telepon. Setelah konfirmasi, itu semua membutuhkan waktu beberapa detik, dan bahkan pada koneksi yang baik bisa 3-5 detik, dan pada koneksi yang buruk semua 10.
Kita harus melakukan sesuatu tentang itu! Anda akan memberi tahu saya bahwa semuanya dapat dilakukan dengan sangat sederhana.

Jika Anda sudah memiliki koneksi terbuka untuk aplikasi Anda, Anda dapat segera mengirim push untuk membuat koneksi, terhubung ke server signaling yang diinginkan dan segera mulai membuat panggilan.
Lalu optimasi lain. Bahkan jika telepon masih berdering di saku Anda dan Anda belum mengangkat telepon, Anda sebenarnya dapat bertukar informasi tentang codec yang didukung, alamat IP eksternal, mulai mengirim paket video kosong, dan secara umum semuanya akan menghangat. Setelah Anda mengangkat telepon, semuanya akan menjadi luar biasa.
Kami melakukannya, dan sepertinya semuanya keren. Tapi tidak.

Masalah pertama adalah bahwa pengguna sering membatalkan panggilan. Mereka mengklik "Panggil" dan segera membatalkan. Dengan demikian, dorongan masuk ke panggilan, dan pengguna menghilang (dia telah kehilangan Internet atau yang lainnya). Sementara itu, telepon seseorang berdering, ia mengangkat telepon, dan ia tidak diharapkan di sana. Karena itu, pengoptimalan primitif kami untuk mulai menelepon secepat mungkin tidak benar-benar berfungsi.

Dengan pembatalan panggilan cepat, ada hal berbahaya kedua. Jika Anda menghasilkan ID percakapan Anda di server, maka Anda harus menunggu jawaban. Artinya, Anda membuat panggilan, mendapatkan ID, dan hanya setelah itu Anda dapat melakukan apa pun yang Anda inginkan: mengirim paket, bertukar, termasuk membatalkan panggilan. Ini adalah cerita yang sangat buruk, karena ternyata sampai tanggapan telah tiba, Anda tidak dapat benar-benar membatalkan apa pun dari klien. Oleh karena itu, yang terbaik adalah membuat beberapa jenis ID pada klien seperti GUID dan mengatakan bahwa Anda memulai panggilan. Orang sering melakukan ini: mereka memanggil, membatalkan, dan segera menelepon lagi. Untuk mencegah agar tidak berantakan, lakukan GUID dan kirimkan.

Tampaknya tidak ada apa-apa, tetapi ada masalah lain. Jika Bob memiliki dua telepon, atau di tempat lain peramban tetap terbuka, maka seluruh skema sulap kami untuk bertukar paket, membuat sambungan tidak berfungsi jika ia tiba-tiba menjawab dari perangkat lain.
Apa yang harus dilakukan Mari kita kembali ke skema pensinyalan lambat dasar yang sederhana dan mengoptimalkannya, mengirim dorongan sedikit lebih awal. Pengguna akan mulai terhubung lebih cepat, tetapi ini akan menghemat beberapa uang.

Apa yang harus dilakukan dengan bagian terlama setelah dia mengangkat telepon dan memulai pertukaran?

Anda dapat melakukan hal berikut. Jelas bahwa Alice sudah mengetahui semua codec-nya dan dapat mengirimnya ke kedua ponsel Bob. Dia dapat menyelesaikan semua alamat IP-nya dan juga mengirimnya ke pensinyalan, yang akan membuat mereka dalam antriannya, tetapi tidak akan mengirim ke klien mana pun sehingga mereka dapat mulai menghubungkannya terlebih dahulu.
? offer, , , , , , . , codec negotiation, signaling , , . Candidates signaling.
, signaling . , , .
. Google Duo WhatsApp.

, - . , signaling, , , , , , . .
?
: , . , , β signaling , , - , , , .

, , , . . , , , , . , .
, 24/7, -, .

web-socket - load balancer, signaling- -, . Zookeeper Leader Election, signaling, conversation. conversation, .
,
NewSQL Cassandra . , . , signaling, , signaling, - , Leader Election Zookeeper, , , .
:
- - , , IP signaling
- Signaling , .
- , , , , .
- .
, .
Cassandra, (
).
, :- iceServers ;
- Session Description Protocol;
- ;
- signaling WebRTC , IP ;
- !
:Wow!

Security. Man in the middle attack for WebRTC
man in the middle attack for WebRTC. , WebRTC , RTP, 1996 , SDP 1998 SIP.

β RFC RTP, RTP WebRTC.
RFC β audio level, , audio level , . , SDP, , . congestion, -.
WebRTC . 2011 , 2013 Firefox, iOS/Android, 2014 Opera. , - , .

signaling, , DTLS Handshake . , signaling, «» , , , .

, , , HTTPS, WSS .. β ZRTP, , , Telegram.
Telegram , , . , , , , p2p .
Bagaimana cara kerjanya?

β . , , . . K, , , .
, , K
1 K
2 . . . K
1 K
2 , . K
1 K
2 : , β , β , . , , - , , .
- «» NAT type symmetric NAT.
- , : 2 relay, , CDN; .
- , .
- signaling.

, RTMFP, , WebRTC, , . ! 4 .
, :
, .
HighLoad++ 4-.
, . , 19 (10 9 -) , - . , , .