Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence

Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
Software jako služba, Infrastruktura jako služba, Platforma jako služba, Komunikační platforma jako služba, Videokonference jako služba a co Cloud Gaming jako služba? Již bylo několik pokusů vytvořit cloudové hry (Cloud Gaming), jako je Stadia, kterou nedávno spustil Google. Stadia není novinkou ve WebRTC, ale mohou ostatní používat WebRTC stejným způsobem?

Thanh Nguyen se rozhodl tuto možnost otestovat na svém open source projektu CloudRetro. CloudRetro je založen na Pion, populární Knihovna WebRTC založená na Go (díky Shownu od vývojového týmu Pion za pomoc s tímto článkem). V tomto článku Thanh poskytuje přehled architektury svého projektu a také mluví o tom, co se naučil užitečného a s jakými problémy se při práci setkal.

Vstup

Minulý rok, když Google oznámil Stadii, byl jsem nadšen. Myšlenka je tak jedinečná a inovativní, že jsem neustále přemýšlel, jak je to možné s existující technologií. Touha lépe porozumět tomuto tématu mě přiměla k vytvoření vlastní verze open source cloudové hry. Výsledek byl prostě fantastický. Níže bych se rád podělil o proces práce na mém ročním projekt.

TLDR: verze s krátkým diapozitivem se zvýrazněním

Proč je cloudové hraní budoucností

Věřím, že Cloud Gaming se brzy stane novou generací nejen her, ale i dalších oblastí informatiky. Cloudové hraní je vrcholem modelu klient/server. Tento model maximalizuje backend management a minimalizuje frontendovou práci tím, že hostuje herní logiku na vzdáleném serveru a streamuje obrázky/audio klientovi. Server provádí náročné zpracování, takže klient již nepodléhá hardwarovým omezením.

Google Stadia vám v podstatě umožňuje hrát AAA hry (tj. špičkové trháky) na rozhraní, jako je YouTube. Stejnou metodiku lze aplikovat na další náročné offline aplikace, jako je operační systém nebo 2D/3D grafický design atd. abychom je mohli stabilně provozovat na zařízeních s nízkou specifikací napříč platformami.

Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
Budoucnost této technologie: představte si, že by Microsoft Windows 10 běžel v prohlížeči Chrome?

Cloudové hraní je technicky náročné

Hraní je jednou z těch vzácných oblastí, kde je vyžadována neustálá rychlá reakce uživatele. Pokud se občas setkáme se zpožděním 2 sekund při kliknutí na stránku, je to přijatelné. Živé videostreamy mají tendenci být o několik sekund pozadu, ale stále nabízejí slušné množství použitelnosti. Pokud je ale hra často zpožděna o 500 ms, hrát to prostě nejde. Naším cílem je dosáhnout extrémně nízké latence, aby mezera mezi vstupem a médiem byla co nejmenší. Tradiční přístup ke streamování videa zde tedy nelze použít.

Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
Obecná šablona cloudové hry

Open source projekt CloudRetro

Rozhodl jsem se vytvořit testovací vzorek cloudové hry, abych zjistil, zda je toto vše možné s tak přísnými omezeními sítě. Vybral jsem si Golang pro důkaz konceptu, protože je to jazyk, který znám nejlépe a dobře se hodí pro tuto implementaci z mnoha dalších důvodů, jak jsem později zjistil. Go je jednoduchý a vyvíjí se velmi rychle; Kanály v Go jsou skvělé pro správu multithreadingu.

projekt CloudRetro.io je cloudová herní služba s otevřeným zdrojovým kódem pro retro hry. Cílem projektu je přinést co nejpohodlnější herní zážitek do tradičních retro her a přidat multiplayer.
Více o projektu se můžete dozvědět zde: https://github.com/giongto35/cloud-game.

Funkce CloudRetro

CloudRetro využívá retro hry k předvedení síly cloudového hraní. To vám umožní získat spoustu jedinečných herních zážitků.

  • Přenositelnost hry
    • Okamžité přehrávání při otevření stránky; není potřeba stahování a instalace
    • Běží na mobilním prohlížeči, takže ke spuštění není potřeba žádný software

  • Herní relace lze sdílet na více zařízeních a ukládat do cloudu pro další přihlášení
  • Hru lze streamovat nebo ji můžete hrát s několika uživateli najednou:
    • Crowdplay jako TwitchPlayPokemon, jen více multiplatformní a více v reálném čase
    • Offline hry online. Mnoho uživatelů může hrát bez nastavení sítě. Samurai Shodown lze nyní hrát se 2 hráči přes síť CloudRetro

    Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
    Demo verze online hry pro více hráčů na různých zařízeních

    infrastruktura

    Zásobník požadavků a technologií

    Níže je uveden seznam požadavků, které jsem si stanovil před zahájením projektu.

    1. Jeden hráč
    Tento požadavek se zde nemusí zdát příliš důležitý a zřejmý, ale je to jeden z mých klíčových poznatků, udržuje cloudové hraní co nejdále od tradičních streamovacích služeb. Pokud se zaměříme na hru pro jednoho hráče, můžeme se zbavit centralizovaného serveru nebo CDN, protože nemusíme streamovat k masám. Namísto nahrávání datových proudů na server pro příjem nebo předávání paketů na centralizovaný server WebSocket jsou datové proudy služeb streamovány přímo k uživateli prostřednictvím rovnocenného připojení WebRTC.

    2. Proud médií s nízkou latencí
    Když čtu o Stadii, často vidím v některých článcích zmíněný WebRTC. Uvědomil jsem si, že WebRTC je vynikající technologie a je skvělá pro použití v cloudových hrách. WebRTC je projekt, který poskytuje webovým prohlížečům a mobilním aplikacím komunikaci v reálném čase prostřednictvím jednoduchého API. Poskytuje konektivitu peer-to-peer, je optimalizován pro média a má vestavěné standardní kodeky, jako jsou VP8 a H264.

    Upřednostnil jsem poskytování nejlepší možné uživatelské zkušenosti před zachováním vysoce kvalitní grafiky. Některé ztráty jsou v algoritmu povoleny. Google Stadia má další krok ke zmenšení velikosti obrázku na serveru a snímky jsou před předáním ostatním převedeny na vyšší kvalitu.

    3. Distribuovaná infrastruktura s geografickým směrováním
    Bez ohledu na to, jak optimalizovaný je kompresní algoritmus a kód, je síť stále rozhodujícím faktorem, který nejvíce přispívá k latenci. Architektura by měla mít mechanismus pro párování serveru nejblíže k uživateli, aby se zkrátila doba oběhu (RTT). Architektura by měla mít 1 koordinátora a několik streamovacích serverů distribuovaných po celém světě: Západ USA, Východ USA, Evropa, Singapur, Čína. Všechny streamovací servery musí být zcela izolované. Systém může upravit svou distribuci, když se server připojí nebo opustí síť. Při vysokém provozu tedy přidání dalších serverů umožňuje horizontální škálování.

    4. Kompatibilita s prohlížečem
    Cloudové hraní je nejlepší, když vyžaduje od uživatelů naprosté minimum. To znamená, že je možné spustit v prohlížeči. Prohlížeče pomáhají uživatelům učinit herní zážitek co nejpohodlnějším, protože je šetří instalací softwaru a hardwaru. Prohlížeče také pomáhají poskytovat multiplatformní verze pro mobilní a stolní počítače. Naštěstí je WebRTC dobře podporován v různých prohlížečích.

    5. Jasné oddělení herního rozhraní a služby
    Službu cloudových her vnímám jako platformu. Každý by měl mít možnost připojit k platformě cokoli. Nyní jsem se integroval LibRetro s cloudovou herní službou, protože LibRetro nabízí krásné rozhraní emulátoru her pro retro hry jako SNES, GBA, PS.

    6. Místnosti pro multiplayer, davové hraní a externí propojení (deep-link) s hrou
    CloudRetro podporuje mnoho nových her, jako je CrowdPlay a Online MultiPlayer pro retro hry. Pokud několik uživatelů otevře stejný přímý odkaz na různých počítačích, uvidí stejnou hru spuštěnou a dokonce se k ní budou moci připojit.

    Herní stavy se navíc ukládají do cloudového úložiště. To umožňuje uživatelům pokračovat ve hře kdykoli na jakémkoli jiném zařízení.

    7. Horizontální měřítko
    Jako každý SAAS v současnosti musí být cloudové hraní navrženo tak, aby bylo horizontálně škálovatelné. Návrh koordinátor-pracovník vám umožňuje přidat další pracovníky, aby obsluhovali větší provoz.

    8. Není vázán na jeden mrak
    Infrastruktura CloudRetro je hostována různými poskytovateli cloudu (Digital Ocean, Alibaba, vlastní poskytovatel) pro různé regiony. Povoluji běh v infrastrukturním kontejneru Docker a konfiguruji nastavení sítě pomocí bash skriptu, abych nebyl závislý na jediném poskytovateli cloudu. Když to zkombinujeme s NAT Traversal ve WebRTC, můžeme mít flexibilitu nasadit CloudRetro na jakékoli cloudové platformě a dokonce i na libovolném počítači uživatele.

    Architektonický design

    Pracovník: (nebo výše zmíněný streamovací server) násobí hry, spouští kanál kódování a streamuje zakódovaná média uživatelům. Instance pracovníků jsou distribuovány po celém světě a každý pracovník může zpracovávat více uživatelských relací současně.

    Koordinátor: je zodpovědný za spárování nového uživatele s nejvhodnějším streamovacím pracovníkem. Koordinátor komunikuje s pracovníky přes WebSocket.

    Úložiště stavu hry: centrální vzdálené úložiště pro všechny herní stavy. Toto úložiště poskytuje důležité funkce, jako je vzdálené ukládání/načítání.

    Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
    CloudRetro architektura nejvyšší úrovně

    Vlastní skript

    Když nový uživatel otevře CloudRetro v krocích 1 a 2 zobrazených na obrázku níže, bude koordinátor spolu se seznamem dostupných pracovníků požádán na první stránku. Poté, v kroku 3, klient vypočítá zpoždění pro všechny kandidáty pomocí HTTP požadavku ping. Tento seznam zpoždění je poté zaslán zpět koordinátorovi, aby mohl určit nejvhodnějšího pracovníka, který bude uživateli sloužit. Krok 4 níže vytvoří hru. Mezi uživatelem a přiřazeným pracovníkem je vytvořeno streamované připojení WebRTC.
    Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
    Vlastní skript po získání přístupu

    Co je uvnitř pracovníka

    Herní a streamovací kanály jsou uloženy uvnitř pracovníka v izolaci a vyměňují si zde informace prostřednictvím rozhraní. V současné době se tato komunikace provádí přenosem dat v paměti golang kanály ve stejném procesu. Dalším cílem je segregace, tzn. nezávislé spuštění hry v jiném procesu.

    Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
    Interakce pracovních složek

    Hlavní komponenty:

    • WebRTC: komponenta klienta, která přijímá uživatelský vstup a vydává kódovaná média ze serveru.
    • Emulátor hry: herní složka. Díky knihovně Libretro je systém schopen spustit hru ve stejném procesu a interně zachytit média a vstupní proud.
    • Snímky ve hře jsou zachyceny a odeslány do kodéru.
    • Kodér obrazu/zvuku: kódovací kanál, který přijímá mediální snímky, kóduje je na pozadí a vydává kódované obrázky/audio.

    uskutečnění

    CloudRetro spoléhá na WebRTC jako páteřní technologii, takže než se ponořím do detailů implementace Golang, rozhodl jsem se mluvit o samotném WebRTC. Je to úžasný kus technologie, který mi nesmírně pomohl při dosahování streamování pod sekundou latence.

    WebRTC

    WebRTC je navržen tak, aby poskytoval vysoce kvalitní připojení peer-to-peer v nativních mobilních aplikacích a prohlížečích pomocí jednoduchých rozhraní API.

    NAT Traversal

    WebRTC je známý svou funkcí NAT Traversal. WebRTC je navržen pro komunikaci typu peer-to-peer. Jeho účelem je najít nejvhodnější přímou cestu, která se vyhýbá branám NAT a firewallům, k peer-to-peer prostřednictvím procesu tzv. ICE. V rámci tohoto procesu najdou rozhraní API WebRTC vaši veřejnou IP adresu pomocí serverů STUN a předají ji přenosovému serveru (OTÁČET SE), když nelze navázat přímé spojení.

    CloudRetro však tuto schopnost plně nevyužívá. Jeho peer-to-peer spojení neexistují mezi uživateli, ale mezi uživateli a cloudovými servery. Serverová strana modelu má méně omezení přímé komunikace než typické uživatelské zařízení. To vám umožní předem otevřít příchozí porty nebo přímo použít veřejné IP adresy, protože server není za NAT.

    Dříve jsem chtěl z projektu udělat platformu pro distribuci her pro Cloud Gaming. Cílem bylo umožnit tvůrcům her poskytovat hry a zdroje pro streamování. A uživatelé by komunikovali přímo s poskytovateli. V tomto decentralizovaném způsobu je CloudRetro pouze médiem pro připojení streamovacích zdrojů třetích stran k uživatelům, díky čemuž je škálovatelnější, když na něm již nevisí hosting. Role WebRTC NAT Traversal je zde velmi důležitá pro usnadnění inicializace připojení peer-to-peer na streamovacích zdrojích třetích stran, což tvůrci usnadňuje připojení k síti.

    Komprese videa

    Komprese videa je nepostradatelnou součástí potrubí a velkou měrou přispívá k plynulosti streamu. I když není nutné znát všechny podrobnosti o kódování videa VP8/H264, pochopení tohoto konceptu pomáhá porozumět parametrům rychlosti streamování videa, odladit neočekávané chování a upravit latenci.

    Komprese videa pro streamovací službu je náročná, protože algoritmus musí zajistit, aby celková doba kódování + doba síťového přenosu + doba dekódování byla co nejmenší. Kromě toho musí být proces kódování konzistentní a nepřetržitý. Některé kompromisy v kódování neplatí – nemůžeme například upřednostňovat dlouhou dobu kódování před menší velikostí souboru a dobou dekódování nebo používat nekonzistentní kompresi.

    Myšlenkou komprese videa je eliminovat zbytečné bity informací při zachování přijatelné úrovně věrnosti pro uživatele. Kromě kódování jednotlivých snímků statického obrazu algoritmus odvozuje aktuální snímek z předchozího a následujícího, takže je odeslán pouze jejich rozdíl. Jak můžete vidět na příkladu Pacmana, jsou přenášeny pouze rozdílové body.

    Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
    Porovnání video snímků pomocí Pacman jako příkladu

    Komprese zvuku

    Podobně algoritmus komprese zvuku vynechává data, která lidé nemohou vnímat. Opus je v současnosti nejvýkonnějším zvukovým kodekem. Je navržen pro přenos zvukové vlny přes uspořádaný datagramový protokol, jako je RTP (Real Time Transport Protocol). Jeho zpoždění je menší než u mp3 a aac a kvalita je vyšší. Latence je obvykle kolem 5~66,5 ms.

    Pion, WebRTC v Golangu

    Pěšák je open source projekt, který přináší WebRTC do Golang. Místo obvyklého balení nativních knihoven C++ WebRTC je Pion nativní implementací Golang WebRTC s lepším výkonem, integrací Go a řízením verzí na protokolech WebRTC.

    Knihovna také poskytuje streamování dat se spoustou skvělých vestavěných modulů se zpožděním menším než sekunda. Má vlastní implementaci STUN, DTLS, SCTP atd. a nějaké experimenty s QUIC a WebAssembly. Tato knihovna s otevřeným zdrojovým kódem je sama o sobě opravdu dobrým zdrojem učení se skvělou dokumentací, implementacemi síťových protokolů a skvělými příklady.

    Komunita Pion vedená velmi zapáleným tvůrcem je poměrně živá a o WebRTC vede mnoho kvalitních diskusí. Pokud vás tato technologie zaujala, přidejte se http://pion.ly/slack - naučíte se spoustu nových věcí.

    Psaní CloudRetro v Golangu

    Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
    Worker Implementation in Go

    Přejděte na kanály v akci

    Díky krásnému designu kanálů Go jsou problémy streamování událostí a souběžnosti výrazně zjednodušeny. Stejně jako v diagramu existuje několik komponent běžících paralelně v různých GoRoutinech. Každá komponenta spravuje svůj vlastní stav a komunikuje prostřednictvím kanálů. Golangovo selektivní tvrzení způsobí, že se pokaždé ve hře zpracuje jedna atomová událost (game tick). To znamená, že pro tento návrh není potřeba žádné blokování. Když je například uživatel uložen, je vyžadován úplný snímek stavu hry. Tento stav musí zůstat nepřetržitý, přihlášení se až do dokončení ukládání. Během každé hry může backend zpracovat pouze operaci uložení nebo zadání, díky čemuž je proces bezpečný pro vlákna.

    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

    Tato šablona Golang je skvělá pro můj případ použití CrowdPlay a Multiple Player. Podle tohoto vzoru jsou všechny uživatelské vstupy ve stejné místnosti zabudovány do středního vstupního kanálu. Herní média jsou poté rozmístěna všem uživatelům ve stejné místnosti. Tímto způsobem dosáhneme rozdělení herního stavu mezi více herních relací různých uživatelů.

    Open source cloudové hraní na WebRTC: p2p, multiplayer, nulová latence
    Synchronizace mezi různými relacemi

    Nevýhody Golangu

    Golang není dokonalý. Kanál je pomalý. Ve srovnání s blokováním je kanál Go jednoduše jednodušším způsobem, jak zvládnout souběžné a streamované události, ale kanál neposkytuje nejlepší výkon. Pod kanálem je složitá logika blokování. Proto jsem provedl určité úpravy implementace opětovným použitím zámků a atomických hodnot při výměně kanálů pro optimalizaci výkonu.

    Golangův popelář je navíc nezvladatelný, což občas způsobuje až podezřele dlouhé pauzy. To značně narušuje aplikaci streamování v reálném čase.

    OZUBENÉ KOLO

    Projekt využívá stávající VP8/H264 open source knihovnu Golang pro kompresi médií a Libretro pro herní emulátory. Všechny tyto knihovny jsou pouze obaly pro knihovnu C v Go pomocí OZUBENÉ KOLO. Některé z nevýhod jsou uvedeny v tento příspěvek Dave Cheney. Problémy, kterým jsem čelil:

    • neschopnost zachytit havárii v CGO, dokonce i s Golang RecoveryCrash;
    • neschopnost identifikovat problémové místo výkonu, když nemůžeme detekovat podrobné problémy v CGO.

    Závěr

    Dosáhl jsem svého cíle vymyslet cloudové herní služby a vytvořit platformu, která mi pomůže hrát nostalgické retro hry s mými přáteli online. Tento projekt by nebyl možný bez knihovny Pion a podpory komunity Pion. Jsem nesmírně vděčný za jeho intenzivní rozvoj. Jednoduchá API poskytovaná WebRTC a Pion zajistila bezproblémovou integraci. Můj první proof of concept byl vydán ve stejný týden, přestože jsem si předem nebyl vědom komunikace typu peer-to-peer (P2P).

    Navzdory snadné integraci je P2P streaming skutečně velmi složitou oblastí informatiky. Aby bylo možné vytvořit relaci peer-to-peer, musí se vypořádat se složitostí víceletých síťových architektur, jako je IP a NAT. Při práci na tomto projektu jsem nashromáždil mnoho cenných znalostí o sítích a optimalizaci výkonu, takže všem doporučuji vyzkoušet budování P2P produktů pomocí WebRTC.

    CloudRetro vyhovuje všem případům použití, které jsem z mého pohledu retro hráče očekával. Myslím si však, že v projektu je mnoho oblastí, které mohu zlepšit, jako je zvýšení spolehlivosti a výkonu sítě, poskytování kvalitnější herní grafiky nebo možnost sdílení her mezi uživateli. Tvrdě na tom pracuji. Prosím následuj projekt a podpořte ho, pokud se vám líbí.

Zdroj: www.habr.com

Přidat komentář