ProHoster > Blog > Pentadbiran > Permainan awan sumber terbuka pada WebRTC: p2p, berbilang pemain, kependaman sifar
Permainan awan sumber terbuka pada WebRTC: p2p, berbilang pemain, kependaman sifar
Perisian sebagai perkhidmatan, infrastruktur sebagai perkhidmatan, platform sebagai perkhidmatan, platform komunikasi sebagai perkhidmatan, persidangan video sebagai perkhidmatan, bagaimana pula dengan permainan awan sebagai perkhidmatan? Terdapat beberapa percubaan untuk mencipta permainan awan (Cloud Gaming), seperti Stadia, yang dilancarkan oleh Google baru-baru ini. Stadia bukan baru untuk WebRTC, tetapi bolehkah orang lain menggunakan WebRTC dengan cara yang sama?
Thanh Nguyen memutuskan untuk menguji peluang ini pada projek sumber terbukanya CloudRetro. CloudRetro adalah berdasarkan Pion, popular Pustaka WebRTC berdasarkan Go (terima kasih Ditunjukkan daripada pasukan pembangunan Pion atas bantuan mereka dalam menyediakan artikel ini). Dalam artikel ini, Thanh memberikan gambaran keseluruhan seni bina projeknya, dan juga bercakap tentang perkara berguna yang dipelajarinya dan cabaran yang dihadapinya semasa bekerja.
Entry
Tahun lepas, apabila Google mengumumkan Stadia, ia mengejutkan saya. Idea ini sangat unik dan inovatif sehingga saya sentiasa tertanya-tanya bagaimana ini boleh dilakukan dengan teknologi sedia ada. Keinginan untuk lebih memahami topik ini mendorong saya untuk mencipta versi saya sendiri bagi permainan awan sumber terbuka. Hasilnya sungguh hebat. Di bawah ini saya ingin berkongsi proses bekerja pada tahun saya projek.
TLDR: versi slaid pendek dengan sorotan
Mengapa permainan awan adalah masa depan
Saya percaya bahawa Cloud Gaming tidak lama lagi akan menjadi generasi akan datang bukan sahaja permainan, tetapi juga bidang sains komputer yang lain. Permainan awan ialah kemuncak model klien/pelayan. Model ini memaksimumkan pengurusan bahagian belakang dan meminimumkan kerja bahagian hadapan dengan mengehoskan logik permainan pada pelayan jauh dan menstrim imej/audio kepada pelanggan. Pelayan melakukan pemprosesan berat supaya pelanggan tidak lagi bergantung pada batasan perkakasan.
Google Stadia pada asasnya membolehkan anda bermain permainan AAA (iaitu permainan blokbuster mewah) pada antara muka seperti YouTube. Metodologi yang sama boleh digunakan pada aplikasi luar talian berat yang lain seperti sistem pengendalian atau reka bentuk grafik 2D/3D, dsb. supaya kami boleh menjalankannya secara konsisten pada peranti berspesifikasi rendah merentas berbilang platform.
Masa depan teknologi ini: Bayangkan jika Microsoft Windows 10 dijalankan pada penyemak imbas Chrome?
Permainan awan secara teknikalnya mencabar
Permainan adalah salah satu kawasan yang jarang berlaku di mana tindak balas pengguna yang berterusan dan pantas diperlukan. Jika kadangkala kami mengalami kelewatan 2 saat apabila mengklik pada halaman, ini boleh diterima. Strim video langsung cenderung ketinggalan beberapa saat, tetapi masih menawarkan kebolehgunaan yang munasabah. Walau bagaimanapun, jika permainan kerap ketinggalan 500ms, ia tidak boleh dimainkan. Matlamat kami adalah untuk mencapai kependaman yang sangat rendah supaya jurang antara input dan media adalah sekecil mungkin. Oleh itu, pendekatan tradisional untuk penstriman video tidak boleh digunakan di sini.
Templat Permainan Awan Umum
Projek sumber terbuka CloudRetro
Saya memutuskan untuk mencipta sampel ujian permainan awan untuk melihat sama ada semua ini boleh dilakukan dengan sekatan rangkaian yang begitu ketat. Saya memilih Golang untuk pembuktian konsep kerana ia adalah bahasa yang paling saya kenali dan sangat sesuai untuk pelaksanaan ini atas banyak sebab lain, seperti yang saya temui kemudian. Go adalah mudah dan berkembang dengan sangat cepat; Saluran dalam Go sangat bagus untuk mengurus multithreading.
Projek CloudRetro.io ialah perkhidmatan permainan awan sumber terbuka untuk permainan retro. Matlamat projek ini adalah untuk membawa pengalaman permainan yang paling selesa kepada permainan retro tradisional dan menambah berbilang pemain.
Anda boleh mengetahui lebih lanjut mengenai projek di sini: https://github.com/giongto35/cloud-game.
Fungsi CloudRetro
CloudRetro menggunakan permainan retro untuk menunjukkan kuasa permainan awan. Yang membolehkan anda mendapat banyak pengalaman permainan yang unik.
Mudah alih permainan
Main balik segera apabila membuka halaman; tiada muat turun atau pemasangan diperlukan
Berfungsi dalam penyemak imbas mudah alih, jadi tiada perisian diperlukan untuk menjalankannya
Sesi permainan boleh dikongsi merentas berbilang peranti dan disimpan dalam awan untuk kali seterusnya anda log masuk
Permainan ini boleh distrim, atau ia boleh dimainkan oleh beberapa pengguna sekaligus:
Crowdplay seperti TwitchPlayPokemon, hanya lebih merentas platform dan lebih masa nyata
Permainan luar talian dalam talian. Ramai pengguna boleh bermain tanpa menyediakan rangkaian. Samurai Shodown kini boleh dimainkan oleh 2 pemain melalui rangkaian CloudRetro
Versi demo permainan berbilang pemain dalam talian pada peranti berbeza
Infrastruktur
Keperluan dan tindanan teknologi
Di bawah adalah senarai keperluan yang saya tetapkan sebelum memulakan projek.
1. Seorang pemain
Keperluan ini mungkin tidak kelihatan terlalu penting atau jelas di sini, tetapi ia adalah salah satu perkara penting saya, ia membolehkan permainan awan berada jauh dari perkhidmatan penstriman tradisional yang mungkin. Jika kita memberi tumpuan kepada permainan pemain tunggal, kita boleh menyingkirkan pelayan berpusat atau CDN kerana kita tidak perlu menstrim kepada orang ramai. Daripada memuat naik strim ke pelayan sink atau menghantar paket ke pelayan WebSocket terpusat, aliran perkhidmatan dihantar terus kepada pengguna melalui sambungan WebRTC peer-to-peer.
2. Strim media kependaman rendah
Membaca tentang Stadia, saya sering melihat WebRTC disebut dalam beberapa artikel. Saya menyedari bahawa WebRTC ialah teknologi yang luar biasa dan sesuai untuk digunakan dalam permainan awan. WebRTC ialah projek yang menyediakan pelayar web dan aplikasi mudah alih dengan komunikasi masa nyata melalui API mudah. Ia menyediakan sambungan rakan ke rakan, dioptimumkan untuk media dan mempunyai codec standard terbina dalam seperti VP8 dan H264.
Saya mengutamakan memastikan pengalaman pengguna yang terbaik daripada mengekalkan grafik berkualiti tinggi. Sesetengah kerugian boleh diterima dalam algoritma. Google Stadia mempunyai langkah tambahan untuk mengurangkan saiz imej pada pelayan, dan bingkai ditingkatkan kepada kualiti yang lebih tinggi sebelum dihantar kepada rakan setara.
3. Infrastruktur teragih dengan penghalaan geografi
Tidak kira betapa mengoptimumkan algoritma dan kod mampatan, rangkaian masih merupakan faktor penentu yang paling banyak menyumbang kepada kependaman. Seni bina mesti mempunyai mekanisme untuk memasangkan pelayan yang paling hampir dengan pengguna untuk mengurangkan masa pergi balik (RTT). Seni bina mesti mempunyai 1 penyelaras dan beberapa pelayan penstriman yang diedarkan di seluruh dunia: AS Barat, AS Timur, Eropah, Singapura, China. Semua pelayan penstriman mesti diasingkan sepenuhnya. Sistem boleh melaraskan pengedarannya apabila pelayan menyertai atau meninggalkan rangkaian. Oleh itu, dengan trafik yang besar, menambah pelayan tambahan membolehkan penskalaan mendatar.
4. Keserasian pelayar
Permainan awan adalah yang terbaik apabila ia memerlukan sekurang-kurangnya daripada pengguna. Ini bermakna ia boleh dijalankan dalam penyemak imbas. Penyemak imbas membantu menjadikan pengalaman permainan seselesa mungkin untuk pengguna, menyelamatkan mereka daripada memasang perisian dan perkakasan. Penyemak imbas juga membantu menyediakan fungsi merentas platform antara versi mudah alih dan desktop. Nasib baik, WebRTC disokong dengan baik merentas pelbagai pelayar.
5. Pemisahan yang jelas antara antara muka dan perkhidmatan permainan
Saya melihat perkhidmatan permainan awan sebagai platform. Setiap orang sepatutnya boleh menyambungkan apa sahaja ke platform. Sekarang saya telah bersepadu LibRetro dengan perkhidmatan permainan awan kerana LibRetro menawarkan antara muka emulator permainan yang cantik untuk permainan retro seperti SNES, GBA, PS.
6. Bilik untuk berbilang pemain, permainan orang ramai dan pautan luar (pautan dalam) dengan permainan
CloudRetro menyokong banyak permainan baharu seperti CrowdPlay dan Online MultiPlayer untuk permainan retro. Jika beberapa pengguna membuka pautan dalam yang sama pada komputer yang berbeza, mereka akan melihat permainan berjalan yang sama malah akan dapat menyertainya.
Selain itu, keadaan permainan disimpan dalam storan awan. Ini membolehkan pengguna untuk terus bermain pada bila-bila masa pada mana-mana peranti lain.
7. Skala mendatar
Seperti mana-mana SAAS pada masa kini, permainan awan mesti direka bentuk untuk berskala mendatar. Reka bentuk penyelaras-pekerja membolehkan anda menambah lebih ramai pekerja untuk melayani lebih banyak trafik.
8. Tiada sambungan ke satu awan
Infrastruktur CloudRetro dihoskan pada penyedia awan yang berbeza (Lautan Digital, Alibaba, pembekal tersuai) untuk wilayah yang berbeza. Saya membolehkan berjalan dalam bekas Docker untuk infrastruktur dan mengkonfigurasi tetapan rangkaian menggunakan skrip bash untuk mengelak daripada dikunci ke dalam penyedia awan tunggal. Dengan menggabungkan ini dengan NAT Traversal dalam WebRTC, kami boleh mempunyai fleksibiliti untuk menggunakan CloudRetro pada mana-mana platform awan dan juga pada mana-mana mesin pengguna.
Reka bentuk seni bina
pekerja: (atau pelayan penstriman yang disebutkan di atas) menggandakan permainan, menjalankan saluran paip pengekodan dan menstrim media yang dikodkan kepada pengguna. Contoh pekerja diedarkan ke seluruh dunia dan setiap pekerja boleh mengendalikan berbilang sesi pengguna secara serentak.
Penyelaras: bertanggungjawab untuk menggandingkan pengguna baharu dengan pekerja yang paling sesuai untuk penstriman. Penyelaras berinteraksi dengan pekerja melalui WebSocket.
Storan keadaan permainan: storan jauh pusat untuk semua keadaan permainan. Storan ini menyediakan fungsi penting seperti simpan/beban jauh.
Seni bina peringkat atas CloudRetro
Skrip Tersuai
Apabila pengguna baharu membuka CloudRetro dalam langkah 1 dan 2 yang ditunjukkan dalam rajah di bawah, penyelaras bersama senarai pekerja yang tersedia diminta ke halaman pertama. Selepas ini, dalam langkah 3 pelanggan mengira kelewatan untuk semua calon menggunakan permintaan ping HTTP. Senarai kelewatan ini kemudiannya dihantar semula kepada penyelaras supaya dia boleh menentukan pekerja yang paling sesuai untuk berkhidmat kepada pengguna. Langkah 4 di bawah mencipta permainan. Sambungan penstriman WebRTC diwujudkan antara pengguna dan pekerja yang ditugaskan.
Skrip pengguna selepas mendapat akses
Apa yang ada dalam diri pekerja
Saluran paip permainan dan penstriman disimpan di dalam pekerja secara berasingan dan bertukar maklumat di sana melalui antara muka. Pada masa ini, komunikasi ini dijalankan dengan memindahkan data dalam ingatan melalui saluran Golang dalam proses yang sama. Matlamat seterusnya ialah pengasingan, i.e. pelancaran bebas permainan dalam proses lain.
Interaksi komponen pekerja
Komponen utama:
WebRTC: komponen klien yang menerima input pengguna dan mengeluarkan media yang dikodkan daripada pelayan.
Emulator permainan: komponen permainan. Terima kasih kepada perpustakaan Libretro, sistem ini dapat menjalankan permainan dalam proses yang sama dan memintas media dan aliran input secara dalaman.
Bingkai dalam permainan ditangkap dan dihantar kepada pengekod.
Pengekod Imej/Audio: saluran paip pengekodan yang mengambil bingkai media, mengekodnya di latar belakang dan mengeluarkan imej/audio yang dikodkan.
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
CloudRetro bergantung pada WebRTC sebagai teknologi tulang belakangnya, jadi sebelum menyelami butiran pelaksanaan Golang, saya memutuskan untuk bercakap tentang WebRTC itu sendiri. Ini adalah teknologi hebat yang telah banyak membantu saya dalam mencapai kependaman subsaat untuk data penstriman.
WebRTC
WebRTC direka bentuk untuk menyediakan sambungan peer-to-peer berkualiti tinggi pada apl mudah alih asli dan pelayar menggunakan API mudah.
NAT Traversal
WebRTC terkenal dengan fungsi NAT Traversalnya. WebRTC direka untuk komunikasi rakan ke rakan. Matlamatnya adalah untuk mencari laluan terus yang paling sesuai, mengelakkan gerbang NAT dan tembok api untuk komunikasi rakan ke rakan melalui proses yang dipanggil ICE. Sebagai sebahagian daripada proses ini, API WebRTC mencari alamat IP awam anda menggunakan pelayan STUN dan memajukannya ke pelayan geganti (TUKAR) apabila sambungan langsung tidak dapat diwujudkan.
Walau bagaimanapun, CloudRetro tidak mengeksploitasi sepenuhnya ciri ini. Sambungan peer-to-peernya tidak wujud antara pengguna, tetapi antara pengguna dan pelayan awan. Bahagian pelayan model mempunyai lebih sedikit sekatan komunikasi langsung daripada peranti pengguna biasa. Ini membolehkan anda pra-membuka port masuk atau menggunakan alamat IP awam secara langsung, kerana pelayan tidak berada di belakang NAT.
Sebelum ini, saya mahu menjadikan projek itu sebagai platform pengedaran permainan untuk Cloud Gaming. Ideanya adalah untuk membenarkan pencipta permainan menyediakan permainan dan sumber penstriman. Dan pengguna akan berinteraksi dengan pembekal secara langsung. Dengan cara terdesentralisasi ini, CloudRetro hanyalah rangka kerja untuk menghubungkan sumber penstriman pihak ketiga kepada pengguna, menjadikannya lebih berskala apabila ia tidak lagi dihoskan. Peranan WebRTC NAT Traversal di sini adalah sangat penting untuk memudahkan pemulaan sambungan peer-to-peer pada sumber penstriman pihak ketiga, menjadikannya lebih mudah bagi pencipta untuk menyambung ke rangkaian.
Pemampatan video
Pemampatan video adalah bahagian yang tidak boleh diketepikan dalam saluran paip dan menyumbang sangat kepada aliran yang lancar. Walaupun tidak perlu mengetahui setiap butiran pengekodan video VP8/H264, memahami konsep boleh membantu anda memahami pilihan kelajuan video penstriman, nyahpepijat gelagat yang tidak dijangka dan melaraskan kependaman.
Memampatkan video untuk perkhidmatan penstriman adalah mencabar kerana algoritma mesti memastikan bahawa jumlah masa pengekodan + masa penghantaran rangkaian + masa penyahkodan adalah serendah mungkin. Selain itu, proses pengekodan mestilah konsisten dan berterusan. Sesetengah pertukaran pengekodan tidak digunakanβcontohnya, kami tidak boleh memilih masa pengekodan yang panjang berbanding saiz fail dan masa penyahkodan yang lebih kecil, atau menggunakan pemampatan yang tidak konsisten.
Idea di sebalik pemampatan video adalah untuk menghapuskan bit maklumat yang tidak diperlukan sambil mengekalkan tahap ketepatan yang boleh diterima untuk pengguna. Selain pengekodan bingkai imej statik individu, algoritma menyimpulkan bingkai semasa daripada yang sebelumnya dan seterusnya, jadi hanya perbezaannya dihantar. Seperti yang dapat dilihat dari contoh dengan Pacman, hanya titik pembezaan yang dihantar.
Perbandingan bingkai video menggunakan Pacman sebagai contoh
Pemampatan audio
Begitu juga, algoritma pemampatan audio mengetepikan data yang tidak dapat dilihat oleh manusia. Opus ialah codec audio berprestasi terbaik pada masa ini. Ia direka untuk menghantar gelombang audio melalui protokol datagram yang dipesan seperti RTP (Protokol Pengangkutan Masa Sebenar). Latensinya lebih rendah daripada mp3 dan aac, dan kualitinya lebih tinggi. Latensi biasanya sekitar 5~66,5ms.
Pion, WebRTC di Golang
Pajak gadai ialah projek sumber terbuka yang membawa WebRTC ke Golang. Daripada pembungkusan biasa perpustakaan WebRTC C++ asli, Pion ialah pelaksanaan Golang asli bagi WebRTC dengan prestasi yang lebih baik, penyepaduan Go dan kawalan versi pada protokol WebRTC.
Perpustakaan juga membolehkan penstriman dengan banyak terbina dalam yang hebat dengan kependaman subsaat. Ia mempunyai pelaksanaan STUN, DTLS, SCTP, dll. dan beberapa percubaan dengan QUIC dan WebAssembly. Pustaka sumber terbuka ini sendiri ialah sumber pembelajaran yang sangat baik dengan dokumentasi yang sangat baik, pelaksanaan protokol rangkaian dan contoh yang hebat.
Komuniti Pion, yang diketuai oleh pencipta yang sangat bersemangat, cukup meriah, dengan banyak perbincangan berkualiti sedang berlangsung tentang WebRTC. Jika anda berminat dengan teknologi ini, sertai http://pion.ly/slack β anda akan belajar banyak perkara baharu.
Menulis CloudRetro di Golang
Pelaksanaan pekerja di Go
Pergi Saluran dalam Tindakan
Terima kasih kepada reka bentuk saluran Go yang cantik, masalah penstriman acara dan konkurensi sangat dipermudahkan. Seperti dalam rajah, GoRoutine yang berbeza mempunyai berbilang komponen yang berjalan secara selari. Setiap komponen menguruskan keadaannya dan berkomunikasi melalui saluran. Penegasan terpilih Golang memaksa satu peristiwa atom diproses setiap kali dalam permainan (game tick). Ini bermakna tiada penguncian diperlukan untuk reka bentuk ini. Sebagai contoh, apabila pengguna menyimpan, syot kilat penuh keadaan permainan diperlukan. Keadaan ini harus kekal berterusan, log masuk sehingga simpanan selesai. Semasa setiap tanda permainan, bahagian belakang hanya boleh mengendalikan operasi simpan atau input, menjadikan benang proses selamat.
func (e *gameEmulator) gameUpdate() {
for {
select {
case <-e.saveOperation:
e.saveGameState()
case key := <-e.input:
e.updateGameState(key)
case <-e.done:
e.close()
return
}
}
}
Kipas-masuk/Kipas-keluar
Templat Golang ini sesuai dengan kes penggunaan CrowdPlay dan Multiple Player saya dengan sempurna. Mengikut corak ini, semua input pengguna dalam satu bilik dibina ke dalam saluran masuk pusat. Media permainan kemudiannya digunakan kepada semua pengguna dalam bilik yang sama. Dengan cara ini, kami mencapai pembahagian keadaan permainan antara beberapa sesi permainan pengguna yang berbeza.
Penyegerakan antara sesi yang berbeza
Kelemahan Golang
Golang tidak sempurna. Salurannya perlahan. Berbanding dengan menyekat, saluran Go hanyalah cara yang lebih mudah untuk mengendalikan acara serentak dan berulir, tetapi saluran tidak memberikan prestasi terbaik. Terdapat logik penyekatan yang kompleks di bawah saluran. Jadi saya membuat beberapa pelarasan pada pelaksanaan, menggunakan semula kunci dan nilai atom apabila menggantikan saluran untuk mengoptimumkan prestasi.
Selain itu, pemungut sampah di Golang tidak terurus, yang kadangkala menyebabkan jeda yang mencurigakan. Ini sangat mengganggu aplikasi penstriman masa nyata.
COG
Projek ini menggunakan perpustakaan Golang VP8/H264 sumber terbuka sedia ada untuk pemampatan media dan Libretro untuk emulator permainan. Semua perpustakaan ini hanyalah pembungkus perpustakaan C dalam Go menggunakan COG. Beberapa kelemahan disenaraikan dalam siaran ini oleh Dave Cheney. Masalah yang saya hadapi:
ketidakupayaan untuk menangkap ranap dalam CGO, walaupun dengan Golang RecoveryCrash;
kegagalan untuk mengenal pasti kesesakan prestasi apabila kami tidak dapat mengesan masalah terperinci dalam CGO.
Kesimpulan
Saya mencapai matlamat saya untuk memahami perkhidmatan permainan awan dan mencipta platform yang membantu saya bermain permainan retro nostalgia dengan rakan saya dalam talian. Projek ini tidak akan dapat dilaksanakan tanpa perpustakaan Pion dan sokongan komuniti Pion. Saya amat berterima kasih atas pembangunan intensifnya. API ringkas yang disediakan oleh WebRTC dan Pion memastikan penyepaduan yang lancar. Bukti konsep pertama saya telah dikeluarkan pada minggu yang sama, walaupun saya tidak mempunyai pengetahuan awal tentang komunikasi rakan ke rakan (P2P).
Walaupun kemudahan penyepaduan, penstriman P2P sememangnya bidang yang sangat kompleks dalam sains komputer. Dia perlu menangani kerumitan seni bina rangkaian lama seperti IP dan NAT untuk mencipta sesi peer-to-peer. Semasa mengerjakan projek ini, saya memperoleh banyak pengetahuan berharga tentang rangkaian dan pengoptimuman prestasi, jadi saya menggalakkan semua orang mencuba membina produk P2P menggunakan WebRTC.
CloudRetro memenuhi semua kes penggunaan yang saya jangkakan dari perspektif saya sebagai pemain permainan retro. Walau bagaimanapun, saya fikir terdapat banyak bidang dalam projek yang boleh saya perbaiki, seperti menjadikan rangkaian lebih dipercayai dan berprestasi, menyediakan grafik permainan berkualiti tinggi atau keupayaan untuk berkongsi permainan antara pengguna. Saya bekerja keras untuk ini. Sila ikut projek dan sokong jika anda suka.