Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.

Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
Kot delovna oblika, infrastruktura kot storitev, platforma kot storitev, komunikacijska platforma kot storitev, video konference kot storitev, kaj pa oblačne igre kot storitev? Na področju oblačnih iger (Cloud Gaming) je bilo že nekaj poskusov, na primer Stadia, ki jo je nedavno zagnal Google. ni novinec v WebRTC, vendar lahko tudi drugi uporabijo WebRTC na enak način?

Thanh Nguyen se je odločil preveriti to možnost s svojim odprtokodnim projektom CloudRetro. CloudRetro temelji na Pionu, popularni WebRTC knjižnici, ki temelji na Go (hvala Shonu iz Pionove razvojne skupine za pomoč pri pripravi tega članka). V tem članku Thanh predstavi arhitekturo svojega projekta in deli, kaj je koristnega izvedel ter s katerimi izzivi se je soočil med delom.

Uvod

Lani, ko je Google napovedal Stadia, sem bil popolnoma navdušen. Ideja je tako edinstvena in inovativna, da sem se nenehno spraševal, kako je to sploh mogoče s trenutno tehnologijo. Želja po boljši razumljivosti te tematike me je spodbudila, da sem ustvaril svojo različico odprtokodnih oblačnih iger. Rezultat je bil enostavno fantastičen. Spodaj bi rad delil proces dela na mojem enoletnem projekat.

TLDR: kratka različica s ključnimi točkami

Zakaj so oblačne igre prihodnost

Verjamem, da bo Cloud Gaming kmalu nova generacija ne le iger, temveč tudi drugih področij računalništva. Oblačne igre so vrhunec modela odjemalec/server. Ta model maksimira upravljanje s ​​zadnjim delom in minimizira delo sprednjega dela s tem, da se igralna logika nahaja na oddaljenem strežniku, slike/avdio pa se pretakajo strankam. Strežnik izvaja zahtevno obdelavo, zato odjemalec ni več odvisen od strojne opreme.

Google Stadia praktično omogoča igranje AAA iger (tj. visokoproračunskih blockbuster iger) v vmesniku podobnem YouTubu. Enaka metoda se lahko uporabi tudi za druge zahtevne namizne aplikacije, kot so operacijski sistemi ali 2D/3D grafični dizajn itd., da jih lahko zanesljivo zaženemo na napravah z nizkimi tehničnimi specifikacijami na različnih platformah.

Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
Prihodnost te tehnologije: si predstavljate, če bi Microsoft Windows 10 deloval v brskalniku Chrome?

Oblačne igre so tehnično zahtevne.

Igra je jedno od onih retkih područja gde je potrebna stalna brza reakcija korisnika. Ako se povremeno suočimo sa kašnjenjem od 2 sekunde prilikom klika na stranici, to je prihvatljivo. Video strimovi uživo obično kasne nekoliko sekundi, ali ipak nude dovoljno udobnosti. Ipak, ako igra često kasni 500 ms, jednostavno je nemoguće igrati. Naš cilj je postići izuzetno nisku latenciju, tako da prekid između unosa i medija bude što manji. Stoga tradicionalni pristup striming videu ovde nije primenjiv.

Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
Opšti šablon cloud gaming-a

Open source projekat CloudRetro

Odlučio sam da napravim probni uzorak cloud gaming-a kako bih proverio da li je sve to moguće pod ovim strogo mrežnim ograničenjima. Za proveru koncepta izabrao sam Golang, jer je to jezik koji mi je najpoznatiji i dobro se uklapa za ovu implementaciju iz mnogih drugih razloga, kako se kasnije pokazalo. Go je jednostavan i brzo se razvija; kanali u Go-u su odlični za upravljanje višestrukim nitima.

Projekt CloudRetro.io – cloud gaming servis sa otvorenim izvorom za retro igre. Cilj projekta je da unese najudobnije iskustvo igranja u tradicionalne retro igre i dodati multiplayer.
Detaljnije informacije o projektu možete pronaći ovde: https://github.com/giongto35/cloud-game.

Funkcionalnost CloudRetro

Kako bi se demonstrirala sva moć cloud gaming-a, CloudRetro koristi retro igre. To omogućava dobijanje niza jedinstvenih igračkih iskustava.

  • Pristupačnost igre
    • Trenutno reprodukovanje prilikom otvaranja stranice; preuzimanje i instalacija nisu potrebni
    • Radi u mobilnom pretraživaču, tako da nije potrebno nikakvo softversko rešenje za pokretanje

  • Sesije igranja moguće je zajednički koristiti na više uređaja i čuvati u oblaku za sledeći pristup
  • Igru je moguće streamovati, ili mogu instantno igrati nekoliko korisnika:
    • Crowdplay tipa TwitchPlayPokemon, samo što je više multiplatformski i više u realnom vremenu
    • Offline igre online. Mogu igrati mnogi korisnici bez podešavanja mreže. U Samurai Shodown sada mogu igrati 2 igrača putem CloudRetro mreže

    Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
    Demo verzija multiplayer online igre na različitim uređajima

    Infrastruktura

    Zahtevi i tehnologije

    Ispod je lista zahteva koje sam postavio pre nego što sam započeo projekat.

    1. Eden igralec
    To zahteva se lahko zdi nepomembna in očitna, vendar je to ena izmed mojih ključnih ugotovitev, ki omogoča, da se oblačne igre kar se da oddaljijo od tradicionalnih streaming storitev. Če se osredotočimo na enojne igralce, se lahko izognemo centraliziranemu strežniku ali CDN, ker ni potrebno streamati množicam. Namesto da bi nalagali tokove na obremenitveni strežnik ali prenašali pakete na centralizirani WebSocket strežnik, se storitveni tokovi prenašajo neposredno uporabniku prek povezave Peer-to-Peer WebRTC.

    2. Medijski tok z nizko zamudo
    Ko berem o Stadii, pogosto naletim na omembo WebRTC v nekaterih člankih. Spoznal sem, da je WebRTC izjemna tehnologija, ki je zelo primerna za oblačne igre. WebRTC je projekt, ki zagotavlja komunikacijo v realnem času za spletne brskalnike in mobilne aplikacije preko preprostega API-ja. Omogoča peer-to-peer povezavo, optimizirano za medije, in ima vgrajene standardne kodeke, kot sta VP8 in H264.

    Dal sem prednost zagotavljanju čim bolj udobne izkušnje uporabnikov pred ohranjanjem visoke kakovosti grafike. V algoritmu so dopustne nekatere izgube. V Google Stadii je dodaten korak za zmanjšanje velikosti slike na strežniku, in sličice se povečajo na višjo kakovost pred prenosom peer-u.

    3. Distribucijska infrastruktura z geografsko usmeritvijo
    Ne glede na to, kako optimiziran je algoritem za stiskanje in koda, je omrežje še vedno odločilni dejavnik, ki najbolj vpliva na zamudo. Arhitektura mora imeti mehanizem za povezovanje najbližjega strežnika uporabniku za zmanjšanje časa prenosa (RTT). Arhitektura mora imeti 1 koordinatorski strežnik in več streaming strežnikov, razporejenih po svetu: Zahod ZDA, Vzhod ZDA, Evropa, Singapur, Kitajska. Vsi streaming strežniki morajo biti popolnoma izolirani. Sistem lahko prilagodi svoje razporejanje, ko se strežnik pridruži ali izklopi iz omrežja. Tako pri večji obremenitvi dodajanje dodatnih strežnikov omogoča horizontalno razširitev.

    4. Združljivost brskalnika
    Oblačne igre se najbolje prikazuju kada od korisnika zahtevaju minimum. To znači da postoji mogućnost pokretanja u pretraživaču. Pretraživači pomažu da se proces igranja učini što udobnijim za korisnike, oslobađajući ih od instalacije softverske i hardverske opreme. Pretraživači takođe omogućavaju međusobnu kompatibilnost mobilnih i desktop verzija. Na sreću, WebRTC se odlično podržava u različitim pretraživačima.

    5. Jasna podela između korisničkog interfejsa i usluge
    Smatram da je usluga oblačnih igara platforma. Svako treba da ima mogućnost povezivanja bilo čega s platformom. Trenutno sam integrisao LibRetro s uslugom oblačnih igara, jer LibRetro nudi lep interfejs emulatora za retro igre kao što su SNES, GBA, PS.

    6. Sobe za više igrača, crowd play i eksterno povezivanje (deep-link) s igrom
    CloudRetro podržava brojne nove načine igranja, kao što su CrowdPlay i Online MultiPlayer za retro igre. Ako više korisnika otvori isti deep-link na različitim računarima, videće istu pokrenutu igru i čak će moći da joj se pridruže.

    Štaviše, stanja igara se čuvaju u oblačnom skladištu. To omogućava korisnicima da nastave igru u bilo kom trenutku na bilo kojem drugom uređaju.

    7. Horizontalno skaliranje
    Kao i svaka SAAS usluga danas, oblačne igre treba da budu dizajnirane da budu horizontalno skalabilne. Konstrukcija „koordinator-radnik“ omogućava dodavanje više radnika za pružanje većeg saobraćaja.

    8. Nema vezanosti za jedan oblak
    Infrastruktura CloudRetro se smešta na različitim oblačnim provajderima (Digital Ocean, Alibaba, prilagođeni provajder) za različite regione. Aktiviram pokretanje u Docker kontejneru za infrastrukturu i podešavam mrežne parametre pomoću bash skripte kako bih izbegao zavisnost od jednog oblačnog provajdera. Kombinovanjem ovoga sa NAT Traversal u WebRTC, možemo dobiti fleksibilnost za implementaciju CloudRetro na bilo kojoj oblačnoj platformi, pa čak i na računarima bilo kojeg korisnika.

    Arhitektonski dizajn

    Radnik: (ali streaming server, omenjen zgoraj) pomnoži igre, zažene kodirni tok in prenaša kodirane medije uporabnikom. Worker instance se širijo po vsem svetu, vsak worker pa lahko hkrati obdeluje več uporabniških sej.

    Koordinator: je odgovoren za usklajevanje novega uporabnika z najbolj ustreznim workerjem za pretakanje. Koordinator komunicira z workeri prek WebSocket.

    Shranjevanje igralnih stanj: centralno oddaljeno shranjevanje za vsa stanja igre. To shranjevanje zagotavlja pomembne funkcije, kot je oddaljeno shranjevanje/ nalaganje.

    Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
    Višje nivojska arhitektura CloudRetro

    Uporabniški scenarij

    Ko nov uporabnik odpre CloudRetro v korakih 1 in 2, prikazanih na spodnji sliki, se koordinator skupaj s seznamom dostopnih workerjev zahteva na prvi strani. Nato v koraku 3 odjemalec izračuna zakasnitve za vse kandidate z uporabo HTTP ping zahteve. Ta seznam zakasnitev se nato pošlje nazaj koordinatorju, da lahko določi najbolj ustreznega workerja za obravnavo uporabnika. V koraku 4 spodaj se ustvari igra. Med uporabnikom in dodeljenim workerjem se vzpostavi tokovno povezavo WebRTC.
    Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
    Uporabniški scenarij po pridobitvi dostopa

    Kaj je znotraj workerja

    Igralni in pretakajoči tokovi so shranjeni znotraj workerja izolirano in si tam izmenjujejo informacije prek vmesnika. Trenutno se ta povezava izvaja preko prenosa podatkov v pomnilniku po kanalih Golang v istem procesu. Naslednji cilj je segregacija, to je neodvisno zagon igre v drugem procesu.

    Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
    Interakcija komponent workerja

    Glavne sestavine:

    • WebRTC: odjemalska komponenta, ki sprejema uporabniške vnose in posreduje kodirane medije s strežnika.
    • Igralni emulator: igralna komponenta. Z uporabo knjižnice Libretro je sistem sposoben zagnati igro znotraj istega procesa in notranje zajeti medije ter vhodni tok.
    • Utrinki iz igre se zajamejo in pošljejo v kodirnik.
    • Slikovni/avdio kodirnik: kodirni tok, ki sprejema medijske okvirje, jih kodira v ozadju in izhodne kodirane slike/avdio.

    Implementacija

    CloudRetro se zanima za WebRTC kot ključno tehnologijo, zato preden se poglobim v podrobnosti implementacije v Golangu, sem se odločil, da najprej predstavim samo WebRTC. To je neverjetna tehnologija, ki mi je močno pomagala doseči zamudo prenosa podatkov le nekaj delčkov sekunde.

    WebRTC

    WebRTC je namenjen zagotavljanju visokokakovostnih peer-to-peer povezav v nativni mobilni aplikaciji in brskalnikih preko preprostih API-jev.

    NAT Traversal

    WebRTC je znan po svoji funkcionalnosti NAT Traversal. WebRTC je zasnovan za komunikacijo med enakimi. Njegov cilj je najti najbolj optimalno neposredno pot, ki se izogne NAT prehodom in požarnim zidom za peer-to-peer komunikacijo preko procesa, imenovanega ICE. V okviru tega procesa API-ji WebRTC najdejo vaš javni IP naslov s pomočjo STUN strežnikov in ga posredujejo na strežnik za ponovni prenos (TURN), kadar neposredne povezave ni mogoče vzpostaviti.

    Vendar CloudRetro te možnosti ne izkorišča v celoti. Njegove peer-to-peer povezave ne obstajajo med uporabniki, temveč med uporabniki in oblačnimi strežniki. Strežniški del modela ima manj omejitev za neposredno povezovanje kot običajna uporabniška naprava. To omogoča predhodno odpiranje vhodnih vrat ali uporabo javnih IP naslovov neposredno, saj strežnik ni za NAT.

    V preteklosti sem želel spremeniti projekt v platformo za distribucijo iger za Cloud Gaming. Ideja je bila, da bi ustvarjalcem iger omogočili ponujanje iger in pretočnih virov. Uporabniki pa bi neposredno sodelovali s ponudniki. Na tak decentraliziran način je CloudRetro le okolje za povezovanje zunanjih pretočnih virov z uporabniki, kar omogoča večjo skalabilnost, ko gostovanje ne obremenjuje več njega. Vloga WebRTC NAT Traversal je tukaj zelo pomembna za olajšanje inicializacije peer-to-peer povezave na zunanjih pretočnih virih, kar poenostavi povezovanje ustvarjalca z omrežjem.

    Stiskanje videa

    Stiskanje videa je nujen del delovnega procesa, ki znatno prispeva k gladkemu toku. Čeprav ni nujno, da poznate vse podrobnosti kodiranja videa v VP8/H264, razumevanje koncepta pomaga razumeti parametre hitrosti pretakanja videa, odpraviti nepričakovano vedenje in nastaviti zakasnitev.

    Stiskanje videa za pretakanje je zapletena naloga, ker mora algoritem zagotoviti, da je skupni čas kodiranja + čas prenosa po omrežju + čas dekodiranja čim krajši. Poleg tega mora biti proces kodiranja dosleden in neprekinjen. Nekatere kompromise pri kodiranju ni mogoče uporabiti – na primer, ne moremo dati prednosti daljšemu času kodiranja pred manjšim velikostjo datoteke in časom dekodiranja, ali uporabiti nedosledno stiskanje.

    Ideja stiskanja videa je izključiti odvečne bite informacij, hkrati pa ohraniti sprejemljivo raven natančnosti za uporabnike. Poleg kodiranja posameznih statičnih slikovnih okvirjev algoritem izhaja za trenutni okvir iz prejšnjega in naslednjega, tako da se pošlje le njihova razlika. Kot je razvidno iz primera s Pacmanom, se prenašajo le diferencialne točke.

    Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
    Primerjava videokadrov na primeru Pacmana

    Stiskanje zvoka

    Na podoben način algoritem za stiskanje zvoka opušča podatke, ki jih človek ne more zaznati. Opus je trenutno avdio kodek z najboljšo zmogljivostjo. Razvit je za prenos zvočnih valov preko protokola urejenih podatkovnih gramov, kot je RTP (Real-time Transport Protocol – protokol za prenos v realnem času). Njegova zamuda je manjša kot pri mp3 in aac, kakovost pa višja. Zamuda običajno znaša okoli 5~66,5 ms.

    Pion, WebRTC v Golangu

    Pion je projekt z odprto kodo, ki prenaša WebRTC na Golang. Namesto običajnega ovijanja domačih C++ knjižnic WebRTC je Pion izvorna implementacija WebRTC v Golangu z boljšo zmogljivostjo, integracijo z Go in nadzorom različic na protokolih WebRTC.

    Knjižnica prav tako omogoča pretakanje podatkov z veliko odličnimi vgrajenimi moduli, z zamudo manj kot sekundo. Ima svojo lastno implementacijo STUN, DTLS, SCTP itd., pa tudi nekaj eksperimentov s QUIC in WebAssembly. Sama po sebi je ta odprtokodna knjižnica resnično dober vir za učenje z odlično dokumentacijo, implementacijo omrežnih protokolov in odličnimi primeri.

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

    Pisanje CloudRetro v Golangu

    Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
    Implementacija delavca v Go

    Kanali Go v akciji

    Zaradi lepe zasnove kanalov Go so težave s pretakanjem dogodkov in paralelizmom bistveno poenostavljene. Tako kot v diagramu v različnih GoRoutines so vzporedno aktivni različni sestavni deli. Vsaka komponenta upravlja svoje stanje in komunicira prek kanalov. Izbira Golanga zahteva, da se obravnava eno atomsko dejanje vsak trenutek v igri (game tick). To pomeni, da za takšno zasnovo ni potrebna zaklenitev. Na primer, ko se uporabnik shrani, je potreben popoln posnetek stanja igre. To stanje mora ostati neprekinjeno, medtem ko se izvaja vnos, dokler ni shranjevanje zaključeno. Med vsakim game tickom lahko zadnja stran obravnava le operacijo shranjevanja ali vnosa, kar pomeni, da je postopek varno za multi-threading.

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

    Fan-in / Fan-out

    Ta vzorec Golang je odličen za mojo uporabo pri CrowdPlay in več igralcih. V skladu s tem vzorcem se vsi uporabniški vnosi v eni sobi vključijo v osrednji vhodni kanal. Gaming media se nato razdelijo na vse uporabnike v eni sobi. Tako dosežemo delitev stanja igre med več igralnimi sejami različnih uporabnikov.

    Oblačno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.
    Sinhronizacija med različnimi sejami

    Slabosti Golanga

    Golang nije savršen. Kanal je spor. U poređenju sa blokadama, Go kanal je jednostavniji način obrade paralelnih i tokovnih događaja, ali kanal ne pruža najbolju performansu. Pod kanalom postoji složena logika blokiranja. Zato sam napravio neke izmene u implementaciji, ponovo koristeći blokade i atomske vrednosti prilikom zamene kanala radi optimizacije performansi.

    Pored toga, garbage collector u Golangu nije upravljan, zbog čega ponekad dolazi do sumnjivo dugih pauza. Ovo znatno ometa rad aplikacije u realnom vremenu.

    CGO

    U projektu se koristi postojeća VP8/H264 biblioteka Golang sa otvorenim izvorom za kompresiju medija i Libretro za emulatore igara. Sve ove biblioteke su jednostavne omotnice C biblioteke u Go koristeći CGO. Neki od nedostataka su navedeni u ovom postu Davea Cheneya. Problemi sa kojima sam se suočio:

    • nemogućnost hvatanja pada u CGO, čak i uz pomoć Golang RecoveryCrash;
    • nemogućnost određivanja uskog grla u performansama kada ne možemo otkriti detaljne probleme u CGO.

    Zaključek

    Postigao sam svoj cilj – razumeo sam usluge cloud gaming-a i razvio platformu koja pomaže igranje nostalgičnih retro igara s mojim prijateljima online. Stvaranje ovog projekta ne bi bilo moguće bez Pion biblioteke i podrške Pion zajednice. Izuzetno sam zahvalan na njegovom intenzivnom razvoju. Jednostavni API-ji koje pružaju WebRTC i Pion omogućili su glatku integraciju. Moja prva konceptualna dokazna verzija je objavljena u istom nedelji, iako prethodno nisam znao o peer-to-peer vezi (P2P).

    Uprkos jednostavnosti integracije, P2P strimovanje je zaista veoma složena oblast u računarstvu. Bavi se složenošću višegodišnjih mrežnih arhitektura, kao što su IP i NAT, za stvaranje peer-to-peer sesije. Tokom rada na ovom projektu, stekao sam mnogo dragocenih znanja o mrežama i optimizaciji performansi, pa preporučujem svima da pokušaju izgraditi P2P proizvode uz pomoć WebRTC.

    CloudRetro pokriva sve upotrebe koje sam očekivao kao retro gejmer. Ipak, mislim da postoji mnogo oblasti u projektu koje mogu poboljšati, kao što su učiniti mrežu pouzdanijom i efikasnijom, obezbediti bolji kvalitet grafike igara ili omogućiti deljenje igara među korisnicima. Naporno radim na tome. Molim vas, pratite projekat i podržite ga ako vam se sviđa.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster