Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev

Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
Programska oprema kot storitev, infrastruktura kot storitev, platforma kot storitev, komunikacijska platforma kot storitev, videokonference kot storitev, kaj pa igranje iger v oblaku kot storitev? Bilo je že več poskusov ustvarjanja iger v oblaku (Cloud Gaming), kot je Stadia, ki jo je nedavno predstavil Google. Stadia WebRTC ni nov, vendar lahko drugi uporabljajo WebRTC na enak način?

Thanh Nguyen se je odločil preizkusiti to priložnost na svojem odprtokodnem projektu CloudRetro. CloudRetro temelji na Pionu, priljubljena Knjižnica WebRTC, ki temelji na Go (hvala Prikazano od razvojne ekipe Pion za pomoč pri pripravi tega članka). V tem članku Thanh podaja pregled arhitekture svojega projekta, govori pa tudi o tem, kaj koristnega se je naučil in na kakšne izzive je naletel med svojim delom.

Začetek

Lansko leto, ko je Google napovedal Stadio, me je presenetilo. Ideja je tako edinstvena in inovativna, da sem se ves čas spraševal, kako je to sploh mogoče z obstoječo tehnologijo. Želja po boljšem razumevanju te teme me je spodbudila, da sem ustvaril svojo različico odprtokodne igre v oblaku. Rezultat je bil preprosto fantastičen. Spodaj bi rad delil proces dela na svojem letniku projekt.

TLDR: kratka diapozitivna različica s poudarki

Zakaj so igre v oblaku prihodnost

Verjamem, da bo Cloud Gaming kmalu postal naslednja generacija ne le igričarstva, ampak tudi drugih področij računalništva. Igranje v oblaku je vrhunec modela odjemalec/strežnik. Ta model poveča upravljanje zaledja in zmanjša delo na sprednji strani z gostovanjem logike igre na oddaljenem strežniku in pretakanjem slik/zvoka odjemalcu. Strežnik opravi veliko obdelavo, tako da odjemalec ni več prepuščen na milost in nemilost omejitvam strojne opreme.

Google Stadia vam v bistvu omogoča igranje AAA igre (tj. vrhunske uspešnice) na vmesniku, kot je YouTube. Enako metodologijo je mogoče uporabiti za druge težke aplikacije brez povezave, kot je operacijski sistem ali 2D/3D grafično oblikovanje itd. tako da jih lahko dosledno izvajamo na napravah z nizkimi specifikacijami na več platformah.

Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
Prihodnost te tehnologije: Predstavljajte si, da bi Microsoft Windows 10 deloval v brskalniku Chrome?

Igranje iger v oblaku je tehnično zahtevno

Igranje iger je eno tistih redkih področij, kjer je potreben stalen in hiter odziv uporabnika. Če občasno naletimo na 2-sekundni zamik pri kliku na stran, je to sprejemljivo. Pretočni videoposnetki v živo običajno zaostajajo nekaj sekund, vendar še vedno ponujajo primerno uporabnost. Če pa igra pogosto zaostaja za 500 ms, je enostavno ni mogoče igrati. Naš cilj je doseči izjemno nizko zakasnitev, tako da je vrzel med vnosom in medijem čim manjša. Zato tradicionalni pristop k pretakanju videa tukaj ni uporaben.

Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
Splošna predloga igre v oblaku

Odprtokodni projekt CloudRetro

Odločil sem se ustvariti testni vzorec igre v oblaku, da vidim, ali je vse to mogoče s tako strogimi omrežnimi omejitvami. Golang sem izbral za dokaz koncepta, ker je bil to jezik, ki sem ga najbolj poznal, in je bil zelo primeren za to izvedbo iz številnih drugih razlogov, kot sem pozneje odkril. Go je preprost in se razvija zelo hitro; Kanali v Go so odlični za upravljanje večnitnosti.

Projekt CloudRetro.io je odprtokodna igralna storitev v oblaku za retro igre. Cilj projekta je tradicionalnim retro igram prinesti najbolj udobno igralno izkušnjo in dodati več igralcev.
Več o projektu lahko izveste tukaj: https://github.com/giongto35/cloud-game.

Funkcionalnost CloudRetro

CloudRetro uporablja retro igre za prikaz moči igranja v oblaku. Kar vam omogoča številne edinstvene igralne izkušnje.

  • Prenosljivost igre
    • Takojšnje predvajanje ob odpiranju strani; ni potreben prenos ali namestitev
    • Deluje v mobilnem brskalniku, zato za zagon ni potrebna programska oprema

  • Igralne seje lahko delite v več napravah in jih shranite v oblak za naslednjič, ko se prijavite
  • Igro je mogoče pretakati ali pa jo igra več uporabnikov hkrati:
    • Crowdplay kot TwitchPlayPokemon, le da je več platform in bolj v realnem času
    • Igre brez povezave na spletu. Mnogi uporabniki lahko igrajo brez vzpostavitve omrežja. Samurai Shodown lahko zdaj igrata 2 igralca prek omrežja CloudRetro

    Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
    Demo različica spletne igre za več igralcev na različnih napravah

    Infrastruktura

    Zahteve in tehnološki sklop

    Spodaj je seznam zahtev, ki sem jih postavil pred začetkom projekta.

    1. En igralec
    Ta zahteva se tukaj morda ne zdi preveč pomembna ali očitna, vendar je eden od mojih ključnih zaključkov, saj omogoča, da igranje iger v oblaku ostane čim dlje od tradicionalnih storitev pretakanja. Če se osredotočimo na igro za enega igralca, se lahko znebimo centraliziranega strežnika ali CDN, ker nam ni treba pretakati množicam. Namesto nalaganja tokov na ponorni strežnik ali posredovanja paketov centraliziranemu strežniku WebSocket se storitveni tokovi dostavijo neposredno uporabniku prek povezave enakovrednih WebRTC.

    2. Medijski tok z nizko zakasnitvijo
    Ko berem o Stadii, pogosto vidim, da se v nekaterih člankih omenja WebRTC. Spoznal sem, da je WebRTC izjemna tehnologija in popolna za uporabo v igrah v oblaku. WebRTC je projekt, ki spletnim brskalnikom in mobilnim aplikacijam omogoča komunikacijo v realnem času prek preprostega API-ja. Zagotavlja povezljivost enakovrednih, je optimiziran za medije in ima vgrajene standardne kodeke, kot sta VP8 in H264.

    Prednost sem dal zagotavljanju najboljše možne uporabniške izkušnje pred vzdrževanjem visokokakovostne grafike. Nekatere izgube so sprejemljive v algoritmu. Google Stadia ima dodaten korak zmanjšanja velikosti slike na strežniku, okvirji pa se povečajo na višjo kakovost, preden se posredujejo vrstnikom.

    3. Porazdeljena infrastruktura z geografskim usmerjanjem
    Ne glede na to, kako optimizirana sta algoritem stiskanja in koda, je omrežje še vedno odločilni dejavnik, ki največ prispeva k zakasnitvi. Arhitektura mora imeti mehanizem za seznanjanje strežnika, ki je najbližje uporabniku, da se zmanjša čas povratnega potovanja (RTT). Arhitektura mora imeti 1 koordinatorja in več pretočnih strežnikov, porazdeljenih po vsem svetu: zahod ZDA, vzhod ZDA, Evropa, Singapur, Kitajska. Vsi pretočni strežniki morajo biti popolnoma izolirani. Sistem lahko prilagodi svojo porazdelitev, ko se strežnik pridruži ali zapusti omrežje. Tako pri velikem prometu dodajanje dodatnih strežnikov omogoča horizontalno skaliranje.

    4. Združljivost brskalnika
    Igranje v oblaku je najboljše, ko od uporabnikov zahteva najmanj. To pomeni, da je mogoče zagnati v brskalniku. Brskalniki pripomorejo k temu, da je igralna izkušnja za uporabnike kar se da udobna in jim prihrani nameščanje programske in strojne opreme. Brskalniki prav tako pomagajo zagotoviti funkcionalnost med platformami med mobilnimi in namiznimi različicami. Na srečo je WebRTC dobro podprt v različnih brskalnikih.

    5. Jasna ločitev vmesnika igre in storitve
    Na storitev igranja iger v oblaku gledam kot na platformo. Vsak bi moral imeti možnost povezati karkoli s platformo. Zdaj sem integriral LibRetro s storitvijo igranja iger v oblaku, ker LibRetro ponuja čudovit vmesnik emulatorja iger za retro igre, kot so SNES, GBA, PS.

    6. Sobe za igranje več igralcev, množično igro in zunanje povezovanje (globinska povezava) z igro
    CloudRetro podpira veliko novih iger, kot sta CrowdPlay in Online MultiPlayer za retro igre. Če več uporabnikov odpre isto globoko povezavo na različnih računalnikih, bodo videli, da teče ista igra in se ji bodo lahko celo pridružili.

    Poleg tega so stanja igre shranjena v shrambi v oblaku. To uporabnikom omogoča, da kadar koli nadaljujejo z igranjem na kateri koli drugi napravi.

    7. Horizontalno skaliranje
    Kot vsak SAAS v današnjem času mora biti igranje v oblaku zasnovano tako, da je vodoravno razširljivo. Zasnova koordinator-delavec vam omogoča, da dodate več delavcev, da zagotovite več prometa.

    8. Ni povezave z enim oblakom
    Infrastruktura CloudRetro gostuje pri različnih ponudnikih v oblaku (Digital Ocean, Alibaba, ponudnik po meri) za različne regije. Omogočim delovanje v vsebniku Docker za infrastrukturo in konfiguriram omrežne nastavitve s skriptom bash, da se izognem zaklepanju v enega samega ponudnika v oblaku. Če to združimo z NAT Traversal v WebRTC, imamo lahko prilagodljivost za uvajanje CloudRetro na katero koli platformo v oblaku in celo na računalnike katerega koli uporabnika.

    Arhitekturno projektiranje

    Delavec: (ali zgoraj omenjeni strežnik za pretakanje) pomnoži igre, zažene cevovod za kodiranje in uporabnikom pretaka kodirane medije. Delovni primerki so porazdeljeni po vsem svetu in vsak delavec lahko obravnava več uporabniških sej hkrati.

    Koordinator: je odgovoren za seznanjanje novega uporabnika z najprimernejšim delavcem za pretakanje. Koordinator komunicira z delavci preko WebSocketa.

    Shranjevanje stanja igre: centralno oddaljeno shranjevanje za vsa stanja igre. Ta shramba zagotavlja pomembne funkcije, kot je oddaljeno shranjevanje/nalaganje.

    Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
    Vrhunska arhitektura CloudRetro

    Skript po meri

    Ko nov uporabnik odpre CloudRetro v 1. in 2. koraku, prikazanem na spodnji sliki, se na prvi strani zahteva koordinator skupaj s seznamom razpoložljivih delavcev. Po tem odjemalec v 3. koraku izračuna zakasnitve za vse kandidate z uporabo zahteve HTTP ping. Ta seznam zamud se nato pošlje nazaj koordinatorju, da lahko določi najprimernejšega delavca za oskrbo uporabnika. 4. korak spodaj ustvari igro. Med uporabnikom in dodeljenim delavcem se vzpostavi pretočna povezava WebRTC.
    Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
    Uporabniški skript po pridobitvi dostopa

    Kaj je znotraj delavca

    Igre in pretočni cevovodi so shranjeni znotraj delavca v izolaciji in tam izmenjujejo informacije prek vmesnika. Trenutno se ta komunikacija izvaja s prenosom podatkov v pomnilniku prek kanali Golang v istem procesu. Naslednji cilj je segregacija, t.j. neodvisen zagon igre v drugem procesu.

    Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
    Interakcija delovnih komponent

    Glavne komponente:

    • WebRTC: odjemalska komponenta, ki sprejme uporabniški vnos in iz strežnika odda kodirano predstavnost.
    • Emulator igre: komponenta igre. Zahvaljujoč knjižnici Libretro lahko sistem poganja igro znotraj istega procesa in interno prestreže medije in vhodni tok.
    • Okvirji v igri so zajeti in poslani v kodirnik.
    • Kodirnik slike/zvoka: cevovod za kodiranje, ki sprejme predstavnostne okvire, jih kodira v ozadju in odda kodirane slike/zvok.

    Реализация

    CloudRetro se zanaša na WebRTC kot svojo hrbtenično tehnologijo, zato sem se, preden se poglobim v podrobnosti izvedbe Golanga, odločil spregovoriti o samem WebRTC. To je neverjetna tehnologija, ki mi je zelo pomagala pri doseganju podsekundne zakasnitve za pretakanje podatkov.

    WebRTC

    WebRTC je zasnovan za zagotavljanje visokokakovostnih povezav enakovrednih v domačih mobilnih aplikacijah in brskalnikih z uporabo preprostih API-jev.

    Prehod NAT

    WebRTC je znan po svoji funkciji NAT Traversal. WebRTC je zasnovan za komunikacijo enakovrednih. Njegov cilj je najti najprimernejšo neposredno pot, pri čemer se izogiba prehodom NAT in požarnim zidom za komunikacijo enakovrednih prek procesa, imenovanega ICE. Kot del tega postopka API-ji WebRTC poiščejo vaš javni naslov IP s pomočjo strežnikov STUN in ga posredujejo posredovalnemu strežniku (OBRAT), ko neposredne povezave ni mogoče vzpostaviti.

    Vendar CloudRetro te funkcije ne izkorišča v celoti. Njegove povezave enakovrednih ne obstajajo med uporabniki, temveč med uporabniki in strežniki v oblaku. Strežniška stran modela ima manj neposrednih komunikacijskih omejitev kot običajna uporabniška naprava. To vam omogoča, da vnaprej odprete dohodna vrata ali neposredno uporabite javne naslove IP, saj strežnik ni za NAT.

    Prej sem želel projekt spremeniti v platformo za distribucijo iger za Cloud Gaming. Ideja je bila omogočiti ustvarjalcem iger, da zagotovijo igre in pretočne vire. In uporabniki bi neposredno komunicirali s ponudniki. Na ta decentraliziran način je CloudRetro samo okvir za povezovanje pretočnih virov tretjih oseb z uporabniki, zaradi česar je bolj razširljiv, ko ne gostuje več. Vloga WebRTC NAT Traversal je tukaj zelo pomembna za olajšanje inicializacije povezave enakovrednih na pretočnih virih tretjih oseb, kar ustvarjalcu olajša povezavo z omrežjem.

    Video stiskanje

    Kompresija videa je nepogrešljiv del cevovoda in močno prispeva k nemotenemu pretoku. Čeprav ni potrebno poznati vseh podrobnosti video kodiranja VP8/H264, vam lahko razumevanje konceptov pomaga razumeti možnosti hitrosti pretočnega videa, odpraviti napake pri nepričakovanem vedenju in prilagoditi zakasnitev.

    Stiskanje videa za storitev pretakanja je zahtevno, ker mora algoritem zagotoviti čim krajši skupni čas kodiranja + čas omrežnega prenosa + čas dekodiranja. Poleg tega mora biti postopek kodiranja dosleden in kontinuiran. Nekateri kompromisi pri kodiranju ne veljajo – na primer, ne moremo dajati prednosti dolgim ​​časom kodiranja pred manjšimi velikostmi datotek in časom dekodiranja ali uporabljati nedoslednega stiskanja.

    Ideja kompresije videa je odstraniti nepotrebne delce informacij, hkrati pa ohraniti sprejemljivo raven natančnosti za uporabnike. Poleg kodiranja posameznih okvirjev statične slike algoritem sklepa o trenutnem okvirju iz prejšnjega in naslednjega, tako da se pošlje samo njihova razlika. Kot je razvidno iz primera s Pacmanom, se prenašajo samo diferencialne točke.

    Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
    Primerjava video okvirjev na primeru Pacmana

    Kompresija zvoka

    Prav tako algoritem za stiskanje zvoka izpusti podatke, ki jih ljudje ne morejo zaznati. Opus je trenutno najzmogljivejši zvočni kodek. Zasnovan je za prenos zvočnega vala preko urejenega datagramskega protokola, kot je RTP (Real Time Transport Protocol). Njegova zakasnitev je nižja kot pri mp3 in aac, kakovost pa je višja. Zakasnitev je običajno okoli 5~66,5 ms.

    Pion, WebRTC v Golangu

    Zastavljalnica je odprtokodni projekt, ki prinaša WebRTC v Golang. Namesto običajnega ovoja izvornih knjižnic C++ WebRTC je Pion domača Golangova implementacija WebRTC z boljšo zmogljivostjo, integracijo Go in nadzorom različic na protokolih WebRTC.

    Knjižnica omogoča tudi pretakanje z veliko odličnimi vgrajenimi funkcijami s podsekundno zakasnitvijo. Ima lastno implementacijo STUN, DTLS, SCTP itd. in nekaj poskusov s QUIC in WebAssembly. Sama ta odprtokodna knjižnica je res dober učni vir z odlično dokumentacijo, implementacijami omrežnih protokolov in kul primeri.

    Skupnost Pion, ki jo vodi zelo strasten ustvarjalec, je precej živahna, z veliko kakovostnimi razpravami o WebRTC. Če vas ta tehnologija zanima, se pridružite http://pion.ly/slack – izvedeli boste veliko novega.

    Pisanje CloudRetro v Golangu

    Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
    Implementacija delavca v Go

    Go Channels v akciji

    Zahvaljujoč čudoviti zasnovi kanala Go so težave s pretakanjem dogodkov in sočasnostjo močno poenostavljene. Kot v diagramu imajo različne GoRoutine več komponent, ki tečejo vzporedno. Vsaka komponenta upravlja svoje stanje in komunicira prek kanalov. Golangova selektivna trditev prisili, da se vsakič v igri obdela en atomski dogodek (takt v igri). To pomeni, da za ta dizajn ni potrebno zaklepanje. Na primer, ko uporabnik shrani, je potreben celoten posnetek stanja igre. To stanje mora ostati neprekinjeno, prijava, dokler shranjevanje ni dokončano. Med vsakim tikom igre lahko zaledje obravnava samo operacijo shranjevanja ali vnosa, zaradi česar je procesna nit varna.

    func (e *gameEmulator) gameUpdate() {
    for {
    	select {
    		case <-e.saveOperation:
    			e.saveGameState()
    		case key := <-e.input:
    			e.updateGameState(key)
    		case <-e.done:
    			e.close()
    			return
    	}
        }
    }

    Ventilator v/ven

    Ta predloga Golang popolnoma ustreza mojemu primeru uporabe CrowdPlay in Multiple Player. Po tem vzorcu so vsi uporabniški vhodi v enem prostoru vgrajeni v osrednji vhodni kanal. Igralni mediji so nato razporejeni vsem uporabnikom v isti sobi. Na ta način dosežemo razdelitev stanja igre med več igralnih sej različnih uporabnikov.

    Odprtokodno igranje v oblaku na WebRTC: p2p, igra za več igralcev, ničelna zakasnitev
    Sinhronizacija med različnimi sejami

    Slabosti Golanga

    Golang ni popoln. Kanal je počasen. V primerjavi z blokiranjem je kanal Go preprosto lažji način za obravnavo sočasnih in nizanih dogodkov, vendar kanal ne zagotavlja najboljše zmogljivosti. Pod kanalom je zapletena logika blokiranja. Zato sem naredil nekaj prilagoditev implementacije, pri čemer sem pri zamenjavi kanalov znova uporabil ključavnice in atomske vrednosti, da bi optimiziral delovanje.

    Poleg tega je zbiralnik smeti v Golangu neupravljan, kar včasih povzroča sumljivo dolge premore. To močno moti aplikacijo za pretakanje v realnem času.

    ZOBNIK

    Projekt uporablja obstoječo odprtokodno knjižnico Golang VP8/H264 za stiskanje medijev in Libretro za emulatorje iger. Vse te knjižnice so preprosto ovoji knjižnice C v aplikaciji Go ZOBNIK. Nekatere slabosti so navedene v ta objava avtorja Dava Cheneyja. Težave, na katere sem naletel:

    • nezmožnost ujeti zrušitev v CGO, tudi z Golang RecoveryCrash;
    • nezmožnost prepoznavanja ozkih grl v delovanju, ko ne moremo odkriti podrobnih težav v CGO.

    Zaključek

    Dosegel sem svoj cilj razumeti storitve igranja iger v oblaku in ustvariti platformo, ki mi pomaga igrati nostalgične retro igre s prijatelji na spletu. Ta projekt ne bi bil mogoč brez knjižnice Pion in podpore skupnosti Pion. Izredno sem hvaležen za njegov intenziven razvoj. Preprosti API-ji, ki jih ponujata WebRTC in Pion, so zagotovili brezhibno integracijo. Moj prvi dokaz koncepta je bil izdan isti teden, čeprav nisem imel predhodnega znanja o komunikaciji enakovrednih (P2P).

    Kljub enostavnosti integracije je pretakanje P2P res zelo zapleteno področje v računalništvu. Ukvarjati se mora s kompleksnostjo dolgoletnih omrežnih arhitektur, kot sta IP in NAT, da ustvari sejo enakovrednih. Med delom na tem projektu sem pridobil veliko dragocenega znanja o omrežju in optimizaciji delovanja, zato spodbujam vse, da poskusijo zgraditi izdelke P2P z uporabo WebRTC.

    CloudRetro skrbi za vse primere uporabe, ki sem jih pričakoval z moje perspektive retro igralca. Vendar menim, da je v projektu veliko področij, ki jih lahko izboljšam, na primer narediti omrežje bolj zanesljivo in zmogljivo, zagotoviti višjo kakovost grafike iger ali možnost deljenja iger med uporabniki. Trdo delam na tem. Prosim sledite projekt in podprite, če vam je všeč.

Vir: www.habr.com

Dodaj komentar