Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia

Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
Softvér ako služba, infraštruktúra ako služba, platforma ako služba, komunikačná platforma ako služba, videokonferencie ako služba, čo cloudové hranie ako služba? Prebehlo už niekoľko pokusov o vytvorenie cloudových hier (Cloud Gaming), ako je napríklad Stadia, ktorú nedávno spustil Google. Stadia nie je novinkou vo WebRTC, ale môžu ostatní používať WebRTC rovnakým spôsobom?

Thanh Nguyen sa rozhodol otestovať túto príležitosť na svojom open source projekte CloudRetro. CloudRetro je založený na Pion, populárny Knižnica WebRTC založená na Go (vďaka Zobrazené od vývojového tímu Pion za pomoc pri príprave tohto článku). V tomto článku Thanh poskytuje prehľad architektúry svojho projektu a hovorí aj o tom, čo užitočného sa naučil a s akými výzvami sa počas svojej práce stretol.

Vstup

Minulý rok, keď Google oznámil Stadiu, mi to vyrazilo dech. Myšlienka je taká jedinečná a inovatívna, že som sa neustále čudoval, ako je to vôbec možné s existujúcou technológiou. Túžba lepšie porozumieť tejto téme ma podnietila k vytvoreniu vlastnej verzie open-source cloudovej hry. Výsledok bol jednoducho fantastický. Nižšie by som sa rád podelil o proces práce na mojom roku projektu.

TLDR: verzia s krátkym diapozitívom so zvýraznením

Prečo je cloudové hranie budúcnosťou

Verím, že Cloud Gaming sa čoskoro stane ďalšou generáciou nielen hier, ale aj iných oblastí informatiky. Cloudové hry sú vrcholom modelu klient/server. Tento model maximalizuje backend management a minimalizuje frontendovú prácu tým, že hosťuje hernú logiku na vzdialenom serveri a streamuje obrázky/audio klientovi. Server vykonáva náročné spracovanie, takže klient už nie je vydaný na milosť a nemilosť hardvérovým obmedzeniam.

Google Stadia vám v podstate umožňuje hrať AAA hry (t. j. špičkové trháky) na rozhraní, ako je YouTube. Rovnakú metodiku možno použiť aj na iné ťažké offline aplikácie, ako je operačný systém alebo 2D/3D grafický dizajn atď. aby sme ich mohli konzistentne prevádzkovať na zariadeniach s nízkou špecifikáciou na viacerých platformách.

Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
Budúcnosť tejto technológie: Predstavte si, že by Microsoft Windows 10 bežal v prehliadači Chrome?

Cloudové hranie je technicky náročné

Hranie hier je jednou z mála oblastí, kde je potrebná stála a rýchla odozva používateľa. Ak sa občas stretneme s 2-sekundovým oneskorením pri kliknutí na stránku, je to prijateľné. Živé videostreamy majú tendenciu meškať niekoľko sekúnd, ale stále ponúkajú primeranú použiteľnosť. Ak však hra často zaostáva o 500 ms, je jednoducho nehrateľná. Naším cieľom je dosiahnuť extrémne nízku latenciu, aby bola medzera medzi vstupom a médiom čo najmenšia. Tradičný prístup k streamovaniu videa tu preto nie je použiteľný.

Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
Všeobecná šablóna cloudovej hry

Open source projekt CloudRetro

Rozhodol som sa vytvoriť testovaciu vzorku cloudovej hry, aby som zistil, či je toto všetko možné s takými prísnymi sieťovými obmedzeniami. Ako som neskôr zistil, vybral som si Golang ako proof of concept, pretože to bol jazyk, ktorý som najviac poznal a bol vhodný na túto implementáciu z mnohých iných dôvodov. Go je jednoduchý a vyvíja sa veľmi rýchlo; Kanály v Go sú skvelé na správu multithreadingu.

Projekt CloudRetro.io je cloudová herná služba s otvoreným zdrojom pre retro hry. Cieľom projektu je priniesť čo najpohodlnejší herný zážitok do tradičných retro hier a pridať multiplayer.
Viac o projekte sa môžete dozvedieť tu: https://github.com/giongto35/cloud-game.

Funkcia CloudRetro

CloudRetro využíva retro hry na demonštráciu sily cloudových hier. Čo vám umožní získať mnoho jedinečných herných zážitkov.

  • Prenosnosť hry
    • Okamžité prehrávanie pri otvorení stránky; nie je potrebné sťahovanie ani inštalácia
    • Funguje v mobilnom prehliadači, takže na spustenie nie je potrebný žiadny softvér

  • Herné relácie je možné zdieľať na viacerých zariadeniach a uložiť ich v cloude pre ďalšie prihlásenie
  • Hru je možné streamovať alebo ju môžu hrať viacerí používatelia naraz:
    • Crowdplay ako TwitchPlayPokemon, len viac multiplatformový a viac v reálnom čase
    • Offline hry online. Mnoho používateľov môže hrať bez nastavenia siete. Samurai Shodown teraz môžu hrať 2 hráči cez sieť CloudRetro

    Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
    Demo verzia online hry pre viacerých hráčov na rôznych zariadeniach

    Infraštruktúra

    Zásobník požiadaviek a technológií

    Nižšie je uvedený zoznam požiadaviek, ktoré som si stanovil pred spustením projektu.

    1. Jeden hráč
    Táto požiadavka sa tu nemusí zdať príliš dôležitá alebo zrejmá, ale je to jeden z mojich kľúčových poznatkov, pretože umožňuje cloudovým hrám zostať čo najďalej od tradičných streamovacích služieb. Ak sa zameriame na hru pre jedného hráča, môžeme sa zbaviť centralizovaného servera alebo CDN, pretože nemusíme streamovať masy. Namiesto nahrávania tokov na sink server alebo odovzdávania paketov na centralizovaný server WebSocket sa toky služieb doručujú priamo používateľovi prostredníctvom pripojenia typu peer-to-peer WebRTC.

    2. Tok médií s nízkou latenciou
    Keď čítam o Stadii, v niektorých článkoch často vidím zmienku WebRTC. Uvedomil som si, že WebRTC je vynikajúca technológia a je ideálna na použitie v cloudových hrách. WebRTC je projekt, ktorý poskytuje webovým prehliadačom a mobilným aplikáciám komunikáciu v reálnom čase prostredníctvom jednoduchého API. Poskytuje konektivitu typu peer-to-peer, je optimalizovaný pre médiá a má vstavané štandardné kodeky, ako sú VP8 a H264.

    Uprednostnil som zabezpečenie čo najlepšieho používateľského zážitku pred zachovaním vysokej kvality grafiky. Niektoré straty sú v algoritme prijateľné. Google Stadia má ďalší krok, ktorým je zmenšenie veľkosti obrázka na serveri, a snímky sa pred prenosom iným používateľom upravia na vyššiu kvalitu.

    3. Distribuovaná infraštruktúra s geografickým smerovaním
    Bez ohľadu na to, ako optimalizovaný je kompresný algoritmus a kód, sieť je stále rozhodujúcim faktorom, ktorý najviac prispieva k latencii. Architektúra musí mať mechanizmus na spárovanie servera najbližšie k používateľovi, aby sa skrátil čas spiatočnej cesty (RTT). Architektúra musí mať 1 koordinátora a niekoľko streamovacích serverov distribuovaných po celom svete: Západ USA, Východ USA, Európa, Singapur, Čína. Všetky streamovacie servery musia byť úplne izolované. Systém môže upraviť svoju distribúciu, keď sa server pripojí alebo opustí sieť. Pri veľkom prevádzke teda pridanie ďalších serverov umožňuje horizontálne škálovanie.

    4. Kompatibilita s prehliadačmi
    Cloudové hry sú najlepšie vtedy, keď od používateľov vyžadujú najmenej. To znamená, že je možné spustiť v prehliadači. Prehliadače pomáhajú používateľom čo najviac spríjemniť hranie a ušetria ich od inštalácie softvéru a hardvéru. Prehliadače tiež pomáhajú poskytovať multiplatformové funkcie medzi mobilnou a počítačovou verziou. Našťastie je WebRTC dobre podporovaný v rôznych prehliadačoch.

    5. Jasné oddelenie herného rozhrania a služby
    Službu cloudových hier vnímam ako platformu. Každý by mal mať možnosť pripojiť k platforme čokoľvek. Teraz som sa integroval LibRetro s cloudovou hernou službou, pretože LibRetro ponúka krásne rozhranie emulátora hier pre retro hry, ako sú SNES, GBA, PS.

    6. Miestnosti pre multiplayer, davové hry a externé prepojenie (deep-link) s hrou
    CloudRetro podporuje mnoho nových hier, ako napríklad CrowdPlay a Online MultiPlayer pre retro hry. Ak niekoľko používateľov otvorí rovnaký priamy odkaz na rôznych počítačoch, uvidia rovnakú spustenú hru a dokonca sa k nej budú môcť pripojiť.

    Herné stavy sú navyše uložené v cloudovom úložisku. To umožňuje používateľom pokračovať v hraní kedykoľvek na akomkoľvek inom zariadení.

    7. Horizontálne škálovanie
    Ako každý SAAS v súčasnosti, aj cloudové hry musia byť navrhnuté tak, aby boli horizontálne škálovateľné. Dizajn koordinátor-pracovník vám umožňuje pridať ďalších pracovníkov, ktorí budú obsluhovať väčšiu premávku.

    8. Žiadne pripojenie k jednému cloudu
    Infraštruktúra CloudRetro je hosťovaná u rôznych poskytovateľov cloudu (Digital Ocean, Alibaba, vlastný poskytovateľ) pre rôzne regióny. Povolím spustenie v kontajneri Docker pre infraštruktúru a nakonfigurujem nastavenia siete pomocou skriptu bash, aby som sa vyhla uzamknutiu v jednom cloudovom poskytovateľovi. Ak to skombinujeme s NAT Traversal vo WebRTC, môžeme mať flexibilitu pri nasadzovaní CloudRetro na akejkoľvek cloudovej platforme a dokonca aj na počítačoch ľubovoľného používateľa.

    Architektonický dizajn

    pracovník: (alebo vyššie uvedený streamovací server) znásobuje hry, spúšťa kanál kódovania a streamuje zakódované médiá používateľom. Inštancie pracovníkov sú distribuované po celom svete a každý pracovník môže súčasne spracovať viacero používateľských relácií.

    koordinátor: je zodpovedný za spárovanie nového používateľa s najvhodnejším pracovníkom na streamovanie. Koordinátor komunikuje s pracovníkmi cez WebSocket.

    Úložisko stavu hry: centrálne vzdialené úložisko pre všetky herné stavy. Toto úložisko poskytuje dôležité funkcie, ako je vzdialené ukladanie/načítanie.

    Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
    Architektúra najvyššej úrovne CloudRetro

    Vlastný skript

    Keď nový používateľ otvorí CloudRetro v krokoch 1 a 2 zobrazených na obrázku nižšie, koordinátor spolu so zoznamom dostupných pracovníkov sa zobrazí na prvej stránke. Potom klient v kroku 3 vypočíta oneskorenia pre všetkých kandidátov pomocou požiadavky HTTP ping. Tento zoznam oneskorení sa potom pošle späť koordinátorovi, aby mohol určiť najvhodnejšieho pracovníka, ktorý bude slúžiť používateľovi. Krok 4 nižšie vytvorí hru. Medzi používateľom a priradeným pracovníkom sa vytvorí pripojenie na streamovanie WebRTC.
    Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
    Používateľský skript po získaní prístupu

    Čo je vo vnútri pracovníka

    Herné a streamingové kanály sú uložené vo vnútri pracovníka v izolácii a vymieňajú si tam informácie cez rozhranie. V súčasnosti sa táto komunikácia uskutočňuje prenosom údajov v pamäti cez Golang kanály v rovnakom procese. Ďalším cieľom je segregácia, t.j. nezávislé spustenie hry v inom procese.

    Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
    Interakcia pracovných komponentov

    Hlavné komponenty:

    • WebRTC: klientsky komponent, ktorý prijíma užívateľský vstup a vydáva kódované médiá zo servera.
    • Emulátor hry: herný komponent. Vďaka knižnici Libretro je systém schopný spustiť hru v rámci rovnakého procesu a interne zachytávať médiá a vstupný tok.
    • Snímky v hre sú zachytené a odoslané do kódovača.
    • Kódovač obrazu/zvuku: kódovací kanál, ktorý berie mediálne snímky, kóduje ich na pozadí a vydáva zakódované obrázky/audio.

    Реализация

    CloudRetro sa spolieha na WebRTC ako svoju chrbticovú technológiu, takže predtým, ako sa ponorím do detailov implementácie Golang, rozhodol som sa hovoriť o samotnom WebRTC. Toto je úžasná technológia, ktorá mi veľmi pomohla pri dosahovaní subsekundovej latencie pre streamovanie dát.

    WebRTC

    WebRTC je navrhnutý tak, aby poskytoval vysokokvalitné pripojenia typu peer-to-peer v natívnych mobilných aplikáciách a prehliadačoch pomocou jednoduchých rozhraní API.

    NAT Traversal

    WebRTC je známy svojou funkciou NAT Traversal. WebRTC je určený na komunikáciu typu peer-to-peer. Jeho cieľom je nájsť najvhodnejšiu priamu cestu, vyhýbajúc sa bránam NAT a firewallom pre peer-to-peer komunikáciu prostredníctvom procesu tzv. ICE. V rámci tohto procesu rozhrania WebRTC API nájdu vašu verejnú IP adresu pomocou serverov STUN a prepošlú ju na prenosový server (OTOČTE), keď nie je možné vytvoriť priame spojenie.

    CloudRetro však túto funkciu plne nevyužíva. Jeho peer-to-peer pripojenia neexistujú medzi používateľmi, ale medzi používateľmi a cloudovými servermi. Serverová strana modelu má menej priamych komunikačných obmedzení ako typické používateľské zariadenie. To vám umožňuje vopred otvoriť prichádzajúce porty alebo priamo použiť verejné IP adresy, pretože server nie je za NAT.

    Predtým som chcel z projektu urobiť platformu na distribúciu hier pre Cloud Gaming. Cieľom bolo umožniť tvorcom hier poskytovať hry a zdroje na streamovanie. A používatelia by komunikovali priamo s poskytovateľmi. Týmto decentralizovaným spôsobom je CloudRetro len rámec na pripojenie zdrojov streamovania tretích strán k používateľom, vďaka čomu je škálovateľnejší, keď už nie je hosťovaný. Úloha WebRTC NAT Traversal je tu veľmi dôležitá na uľahčenie inicializácie pripojenia peer-to-peer na streamovacích zdrojoch tretích strán, čím sa uľahčí tvorcom pripojenie k sieti.

    Kompresia videa

    Kompresia videa je nenahraditeľnou súčasťou potrubia a výrazne prispieva k plynulému toku. Aj keď nie je potrebné poznať každý detail kódovania videa VP8/H264, pochopenie pojmov vám môže pomôcť pochopiť možnosti rýchlosti streamovaného videa, odladiť neočakávané správanie a upraviť latenciu.

    Kompresia videa pre streamovaciu službu je náročná, pretože algoritmus musí zabezpečiť, aby celkový čas kódovania + čas prenosu siete + čas dekódovania bol čo najnižší. Okrem toho musí byť proces kódovania konzistentný a nepretržitý. Niektoré kompromisy pri kódovaní sa neuplatňujú – napríklad nemôžeme uprednostňovať dlhé časy kódovania pred menšími veľkosťami súborov a časmi dekódovania alebo používať nekonzistentnú kompresiu.

    Myšlienkou kompresie videa je eliminovať nepotrebné kúsky informácií pri zachovaní prijateľnej úrovne presnosti pre používateľov. Okrem kódovania jednotlivých statických snímok, algoritmus odvodzuje aktuálnu snímku z predchádzajúcich a nasledujúcich snímok, takže sa odosiela iba ich rozdiel. Ako vidno z príkladu s Pacmanom, prenášajú sa iba diferenciálne body.

    Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
    Porovnanie video snímok pomocou Pacmana ako príkladu

    Kompresia zvuku

    Podobne algoritmus kompresie zvuku vynecháva údaje, ktoré ľudia nedokážu vnímať. Opus je momentálne najvýkonnejší zvukový kodek. Je navrhnutý na prenos zvukovej vlny cez objednaný datagramový protokol, ako je RTP (Real Time Transport Protocol). Jeho latencia je nižšia ako mp3 a aac a kvalita je vyššia. Latencia je zvyčajne okolo 5 ~ 66,5 ms.

    Pion, WebRTC v Golangu

    pión je open source projekt, ktorý prináša WebRTC do Golang. Namiesto obvyklého balenia natívnych knižníc C++ WebRTC je Pion natívnou implementáciou WebRTC Golang s lepším výkonom, integráciou Go a kontrolou verzií na protokoloch WebRTC.

    Knižnica tiež umožňuje streamovanie s množstvom skvelých vstavaných prvkov s oneskorením pod sekundou. Má vlastnú implementáciu STUN, DTLS, SCTP atď. a niektoré experimenty s QUIC a WebAssembly. Táto knižnica s otvoreným zdrojom je sama o sebe skutočne dobrým vzdelávacím zdrojom s vynikajúcou dokumentáciou, implementáciami sieťových protokolov a skvelými príkladmi.

    Komunita Pion vedená veľmi zanieteným tvorcom je pomerne živá, o WebRTC prebieha množstvo kvalitných diskusií. Ak vás táto technológia zaujala, pridajte sa http://pion.ly/slack – naučíte sa veľa nového.

    Písanie CloudRetro v Golang

    Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
    Implementácia workera v Go

    Prejdite kanály v akcii

    Vďaka nádhernému dizajnu kanála Go sú problémy so streamovaním udalostí a súbežnosťou výrazne zjednodušené. Rovnako ako v diagrame, rôzne GoRoutines majú viacero komponentov bežiacich paralelne. Každý komponent riadi svoj stav a komunikuje cez kanály. Golangovo selektívne tvrdenie núti spracovať vždy jednu atómovú udalosť v hre (tick v hre). To znamená, že pre tento dizajn nie je potrebné žiadne uzamknutie. Napríklad, keď používateľ uloží, vyžaduje sa úplná snímka stavu hry. Tento stav by mal zostať nepretržitý, prihlasovať sa, kým sa nedokončí ukladanie. Počas každého tiknutia hry môže backend spracovať iba operáciu uloženia alebo vstupu, vďaka čomu je procesné vlákno bezpečné.

    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

    Táto šablóna Golang dokonale vyhovuje môjmu prípadu použitia CrowdPlay a viacerých hráčov. Podľa tohto vzoru sú všetky užívateľské vstupy v jednej miestnosti zabudované do centrálneho vstupného kanála. Herné médiá sa potom rozmiestnia všetkým používateľom v rovnakej miestnosti. Týmto spôsobom dosiahneme rozdelenie herného stavu medzi niekoľko herných relácií rôznych používateľov.

    Cloudové hry s otvoreným zdrojom na WebRTC: p2p, multiplayer, nulová latencia
    Synchronizácia medzi rôznymi reláciami

    Nevýhody Golangu

    Golang nie je dokonalý. Kanál je pomalý. V porovnaní s blokovaním je kanál Go jednoducho jednoduchší spôsob, ako zvládnuť súbežné udalosti a udalosti s vláknami, ale kanál neposkytuje najlepší výkon. Pod kanálom je zložitá blokovacia logika. Urobil som teda nejaké úpravy implementácie, znova som použil zámky a atómové hodnoty pri výmene kanálov, aby som optimalizoval výkon.

    Okrem toho je zberač odpadu v Golangu nezvládnutý, čo niekedy spôsobuje až podozrivo dlhé pauzy. To značne zasahuje do aplikácie streamovania v reálnom čase.

    COG

    Projekt využíva existujúcu open source knižnicu Golang VP8/H264 pre kompresiu médií a Libretro pre emulátory hier. Všetky tieto knižnice sú jednoducho obaly knižnice C v Go COG. Niektoré z nevýhod sú uvedené v tento príspevok od Davea Cheneyho. Problémy, s ktorými som sa stretol:

    • neschopnosť zachytiť haváriu v CGO, dokonca aj s Golang RecoveryCrash;
    • zlyhanie pri identifikácii úzkych miest výkonu, keď nedokážeme odhaliť podrobné problémy v CGO.

    Záver

    Dosiahol som svoj cieľ porozumieť cloudovým herným službám a vytvoriť platformu, ktorá mi pomáha hrať nostalgické retro hry s mojimi priateľmi online. Tento projekt by nebol možný bez knižnice Pion a podpory komunity Pion. Som nesmierne vďačný za jeho intenzívny rozvoj. Jednoduché rozhrania API poskytované WebRTC a Pion zaisťovali bezproblémovú integráciu. Môj prvý dôkaz koncepcie bol vydaný v ten istý týždeň, aj keď som nemal žiadne predchádzajúce znalosti o komunikácii typu peer-to-peer (P2P).

    Napriek ľahkej integrácii je P2P streaming skutočne veľmi zložitou oblasťou informatiky. Musí sa vysporiadať so zložitosťou dlhoročných sieťových architektúr, ako sú IP a NAT, aby vytvorila reláciu peer-to-peer. Počas práce na tomto projekte som získal veľa cenných poznatkov o sieťovaní a optimalizácii výkonu, preto všetkým odporúčam, aby si vyskúšali budovanie P2P produktov pomocou WebRTC.

    CloudRetro vyhovuje všetkým prípadom použitia, ktoré som z môjho pohľadu retro hráča očakával. Myslím si však, že v projekte je veľa oblastí, ktoré môžem zlepšiť, ako je napríklad zvýšenie spoľahlivosti a výkonu siete, poskytovanie kvalitnejšej hernej grafiky alebo možnosť zdieľať hry medzi používateľmi. Usilovne na tom pracujem. Prosím nasleduj projektu a podporte to, ak sa vám to páči.

Zdroj: hab.com

Pridať komentár