Szolgáltatásként megvalósított ESET, infrastruktúra mint szolgáltatás, platform mint szolgáltatás, kommunikációs platform mint szolgáltatás, videokonferenciák mint szolgáltatás, mi a helyzet a felhő alapú játékokkal mint szolgáltatással? Már számos kísérlet történt a felhőalapú játékok (Cloud Gaming) létrehozására, például a Stadia, amelyet a Google indított el nemrégiben. Stadia , de tudják-e mások is használni a WebRTC-t ugyanúgy?
Thanh Nguyen úgy döntött, hogy ellenőrzi ezt a lehetőséget az open-source CloudRetro projektjével. A CloudRetro a Pion-ra épül, Go alapú WebRTC könyvtár (köszönjük a Pion fejlesztőcsapatából a cikk előkészítésében nyújtott segítségért). Ebben a cikkben Thanh áttekinti projektje architektúráját, valamint elmondja, hogy mit tanult és milyen kihívásokkal találkozott a munka során.
Bevezetés
Tavaly, amikor a Google bejelentette a Stadiát, egyszerűen lenyűgözött. Az ötlet olyan egyedi és innovatív, hogy folyamatosan azon tűnődtem, hogyan lehetséges ez a meglévő technológiák mellett. Az, hogy jobban megértsem ezt a témát, arra ösztökélt, hogy létrehozzam a saját open-source felhős játékomat. Az eredmény egyszerűen fantasztikus volt. Az alábbiakban szeretném megosztani a munkám folyamatát a három éves .
TLDR: rövid diaképes verzió a főbb pontokkal
Miért van a felhőalapú játékoknak jövője
Hiszem, hogy a Cloud Gaming hamarosan az új generációt képviseli nemcsak a játékokban, hanem más informatikai területeken is. A felhőalapú játékok a kliens/szerver modell csúcsa. Ez a modell maximalizálja a háttérkezelést és minimalizálja a frontend munkáját azzal, hogy a játéklogikát távoli szerveren helyezi el, miközben képek/audio streamelését biztosítja a kliens felé. A szerver végzi a nehéz feldolgozást, így a kliens már nem függ a hardver korlátaitól.
A Google Stadia lényegében lehetővé teszi AAA-játékok Ennek a technológiának a jövője: képzelje el, hogy a Microsoft Windows 10 böngészőben futna, mint a Chrome?

A felhőalapú játékok technikailag bonyolultak.
A felhő alapú játékok technikailag bonyolultak
A játékzás az egyik ritka terület, ahol a felhasználó folyamatos gyors reakciója szükséges. Ha ritkán találkozunk 2 másodperces késéssel a weboldalon, az elfogadható. Az élő videostreaming általában néhány másodperces lemaradással működik, de még mindig megfelelő kényelmet biztosít. Azonban ha a játék gyakran 500 ms-os késleltetést tapasztal, már lehetetlenné válik a játék. Célunk az extrém alacsony késés elérése, hogy a bemenet és a média közötti szakadék a lehető legkisebb legyen. Ezért a hagyományos video streaming megközelítések itt nem alkalmazhatók.

Átfogó sablon a felhős játékhoz
Nyílt forráskódú CloudRetro projekt
Úgy döntöttem, hogy létrehozok egy tesztpéldányt a felhős játékhoz, hogy ellenőrizzem, hogy mindez lehetséges-e ilyen szigorú hálózati korlátok mellett. A koncepció teszteléséhez a Golang-ot választottam, mivel ez a számomra legjobban ismert nyelv, és sok más okból is jól illik ehhez a megvalósításhoz, ahogy később kiderült. A Go egyszerű és nagyon gyorsan fejlődik; a Go csatornák tökéletesen alkalmasak a párhuzamosság kezelésére.
Projekt – nyílt forráskódú felhős játékszolgáltatás retro játékokhoz. A projekt célja, hogy a hagyományos retro játékokba a lehető legkényelmesebb játékélményt hozza, és multiplayer lehetőségeket adjon hozzá.
A projektről részletesen itt tájékozódhat: .
CloudRetro funkcionalitás
A CloudRetro bemutatásához a retro játékok mutatják be a felhős játékok teljes erejét. Ez számos egyedi játékélményt eredményez.
- A játék hordozhatósága
- Azonnali lejátszás az oldal megnyitásakor; letöltés és telepítés nem szükséges
- Mobil böngészőben működik, így nincs szükség szoftver telepítésére a futtatáshoz
- A játék ülését több eszközön megoszthatja, és felhőben tárolhatja a következő bejelentkezéshez
- A játékot streamelheti, vagy több felhasználó egyszerre játszhat benne:
- Crowdplay típusú TwitchPlayPokemon, csak több platformon és valós idejűbb
- Offline játék az online térben. Sok felhasználó játszhat anélkül, hogy a hálózatot be kellene állítani. A Samurai Shodown most már 2 játékos által játszható a CloudRetro hálózatán

Demó verzió a többjátékos online játékhoz különböző eszközökönInfrastruktúra
Követelmények és technológiai stack
Az alábbiakban található a követelmények listája, amelyeket a projekt megkezdése előtt állítottam fel.
1. Egy játékos
Ez a követelmény talán nem tűnik túl fontosnak és nyilvánvalónak itt, de ez az egyik kulcsfontosságú megállapításom, hogy a felhőalapú játékok minél távolabb tarthassák magukat a hagyományos streaming szolgáltatásoktól. Ha a single-player játékra összpontosítunk, megszabadulhatunk a központosított szervertől vagy CDN-től, mert nincs szükségünk arra, hogy tömegesen streameljünk. Ahelyett, hogy folyamokat töltenénk fel egy igénybe vevő szerverre vagy csomagokat küldenénk egy központosított WebSocket szerverre, a szolgáltatói folyamok közvetlenül a felhasználóhoz jutnak el egy peer-to-peer WebRTC kapcsolaton keresztül.2. Alacsony késleltetésű médiastream
Miközben a Stadiáról olvastam, gyakran találkozom a WebRTC említésével egyes cikkekben. Megértettem, hogy a WebRTC egy kiemelkedő technológia, és tökéletesen alkalmas a felhőalapú játékokhoz. A WebRTC egy projekt, amely valós idejű kommunikációt biztosít a web böngészők és mobil alkalmazások számára, egy egyszerű API-n keresztül. Ez egy peer-to-peer kapcsolatot biztosít, amely optimalizált a médiához és beépített szabványos kodekekkel rendelkezik, mint például VP8 és H264.Én a felhasználók maximális kényelmének biztosítását részesítettem előnyben, nem pedig a grafika magas színvonalának megőrzését. Az algoritmusban megengedettek bizonyos veszteségek. A Google Stadiánál van egy plusz lépés a kép méretének csökkentésére a szerveren, így a képkockák magasabb minőségre skálázódnak a peer-to-peer csomópontokhoz való továbbítás előtt.
3. Földrajzi irányítással rendelkező elosztott infrastruktúra
Függetlenül attól, hogy mennyire van optimalizálva a tömörítési algoritmus és a kód, a hálózat továbbra is döntő tényező, amely leginkább hozzájárul a késleltetéshez. Az architektúrának rendelkeznie kell egy mechanizmussal, amely illeszti a felhasználóhoz legközelebbi szervert a késleltetési idő (RTT) csökkentésére. Az architektúrának 1 koordinátorral és több streaming szerverrel kell rendelkeznie, amelyek szerte a világban helyezkednek el: Nyugat-Egyesült Államok, Kelet-Egyesült Államok, Európa, Szingapúr, Kína. Minden streaming szervernek teljesen izoláltnak kell lennie. A rendszer képes kezelni a terjesztését, amikor a szerver csatlakozik a hálózathoz vagy kilép belőle. Így nagy forgalom esetén további szerverek hozzáadása lehetővé teszi a vízszintes skálázást.4. Böngészőkompatibilitás
A felhőalapú játékok legjobban akkor teljesítenek, ha a felhasználóktól a lehető legkevesebb erőforrást igényelnek. Ez azt jelenti, hogy lehetőség van a játékok böngészőben való indítására. A böngészők segítenek a játékélmény maximális kényelmének biztosításában, eltüntetve a szükségességet programok és hardverek telepítésére. A böngészők a mobil és asztali verziók közötti platformfüggetlenséget is segítik. Szerencsére a WebRTC jól támogatott a különböző böngészőkben.5. A játéknak és a szolgáltatásnak a jól elkülönített interfésze
A felhőalapú játékokat platformként tekintek. Mindenki számára lehetőséget kell biztosítani a platformhoz való csatlakozásra. Jelenleg integráltam a felhőalapú játék szolgáltatással, mert a LibRetro szép emulátor felületet kínál retro játékokhoz, például SNES, GBA, PS.6. Multiplayer szobák, crowd play és külső deep-linkelés a játékhoz
A CloudRetro számos új játékformátumot támogat, mint például a CrowdPlay és az Online MultiPlayer retro játékokhoz. Ha több felhasználó ugyanazt a deep-linket nyitja meg különböző számítógépeken, ugyanazt a játékot fogják látni, és akár csatlakozhatnak is hozzá.Továbbá, a játékállapotokat a felhőben tárolják. Ez lehetővé teszi a felhasználók számára, hogy bármikor bármilyen más eszközről folytathassák a játékot.
7. Horizontális skálázhatóság
Mint minden SAAS esetében, a felhőalapú játékokat is úgy kell tervezni, hogy horizontálisan skálázhatóak legyenek. A 'koordinátor-munkás' felépítés lehetővé teszi, hogy további munkásokat adjunk hozzá a nagyobb forgalom kiszolgálásához.8. Nincs kötődés egyetlen felhőszolgáltatóhoz sem
A CloudRetro infrastruktúrája különböző felhőszolgáltatóknál (Digital Ocean, Alibaba, egyedi szolgáltató) található a különböző régiók számára. A Docker konténerben való indítást aktiválom az infrastruktúrára, és bash-szkripttel állítom be a hálózati paramétereket, hogy elkerüljem az egyetlen felhőszolgáltatótól való függőséget. Ezt a NAT Traversal-nal a WebRTC-ben kombinálva rugalmasságot nyerünk a CloudRetro bármely felhőplatformra való telepítéséhez, sőt bármely felhasználó gépén is.Architekturális tervezés
Munkás: (vagy a fent említett stream szerver) megszorozza a játékokat, elindítja a kódoló csővezetéket, és továbbítja a kódolt médiát a felhasználóknak. A worker példányok világszerte eloszlanak, és minden worker több felhasználói munkamenetet is kezelhet egyszerre.
Koordinátor: feladata, hogy új felhasználót összepárosítson a legmegfelelőbb workerrel a streaminghez. A koordinátor WebSocketen keresztül kommunikál a workerekkel.
Játékállapot-tároló: központi távoli tároló minden játékállapot számára. Ez a tároló fontos funkciókat biztosít, mint például a távoli mentés/letöltés.

CloudRetro felső szintű architektúrájaFelhasználói forgatókönyv
Amikor egy új felhasználó megnyitja a CloudRetro-t az alábbi 1. és 2. lépésben, a koordinátor a rendelkezésre álló workerek listájával a kezdőoldalon kérdést kap. Ezután a 3. lépésben az ügyfél HTTP ping kérés segítségével kiszámítja a késleltetéseket minden jelölt esetében. Ez a késleltetési lista ezután vissza kerül a koordinátorhoz, hogy meghatározhassa a legmegfelelőbb worker-t a felhasználó kiszolgálására. Az alábbi 4. lépésben létrejön a játék. A felhasználó és a kijelölt worker között WebRTC streaming kapcsolat áll fel.

Felhasználói forgatókönyv hozzáférés utánMi van a workerben
A játék- és streamingcsővezetések elszigetelten tárolódnak a workerben, és ott információt cserélnek az interfészen keresztül. Jelenleg a kapcsolat az adatok memóriában való átadásával történik a ugyanabban a folyamatban. A következő cél a szegmentálás, azaz a játék független elindítása egy másik folyamatban.

A worker komponenseinek kölcsönhatásaFő alkotóelemek:
- WebRTC: ügyfélkomponens, amely fogadja a felhasználói bemenetet és a kódolt médiát továbbítja a szerverről.
- Játékemulátor: játék komponens. A Libretro könyvtárnak köszönhetően a rendszer képes játékot indítani ugyanabban a folyamatban, és belsőleg elfogni a média- és bemeneti folyamot.
- A játékon belüli képkockák rögzítve lesznek és elküldve a kódolónak.
- Kép/audio kódoló: kódoló csővezeték, amely a média képkockákat fogadja, kódolja őket a háttérben, és kódolt képeket/audio-t állít elő.
Megvalósítás
A CloudRetro a WebRTC-t választotta alaptechnológiájának, ezért mielőtt mélyebben belemerülnék a Golangban való megvalósítás részleteibe, szeretném bemutatni magát a WebRTC-t. Ez egy csodálatos technológia, amely jelentősen segített nekem abban, hogy csak egy tizedmásodperces késleltetést érjek el az adatok streamelésében.
WebRTC
A WebRTC célja a kiváló minőségű, peer-to-peer kapcsolatok biztosítása natív mobilalkalmazások és böngészők számára egyszerű API-kon keresztül.
NAT Traversal
A WebRTC ismert a NAT Traversal funkciójáról. A WebRTC célja a peer-to-peer kommunikáció. Célja, hogy megtalálja a legmegfelelőbb közvetlen útvonalat a NAT átjárók és tűzfalak elkerülésével a peer-to-peer kapcsolat megvalósítása érdekében, egy folyamat során, amelyet . Ebben a folyamatban a WebRTC API-k a STUN szervereken keresztül megtalálják a nyilvános IP-címedet, és azt továbbítják egy relé szerverre (), amikor a közvetlen kapcsolat nem hozható létre.
A CloudRetro azonban nem használja ki teljes mértékben ezt a lehetőséget. A peer-to-peer kapcsolatai nem a felhasználók között, hanem a felhasználók és a felhős szerverek között léteznek. A szerver oldali modellnek kevesebb korlátozása van a közvetlen kapcsolatra, mint a hagyományos felhasználói eszközöknek. Ez lehetővé teszi a bejövő portok előnyitását vagy a nyilvános IP-címek közvetlen használatát, mivel a szerver nem NAT mögött található.
Korábban azt akartam, hogy a projektet a Cloud Gaming játékainak terjesztő platformjává alakítsam. Az ötlet az volt, hogy a játékfejlesztők lehetőséget kapjanak a játékok és streamelt források biztosítására. A felhasználók pedig közvetlenül léptek kapcsolatba a szolgáltatókkal. Ebben a decentralizált formában a CloudRetro csupán közeget jelent a külső streamelt források felhasználókhoz való csatlakoztatásához, ezáltal a méretezhetősége is nő, amikor már nem terheli a hosting. A WebRTC NAT Traversal szerepe itt nagyon fontos a peer-to-peer kapcsolat inicializálásának megkönnyítésében külső streamelt forrásokon, ami egyszerűsíti a fejlesztő és a hálózat összekapcsolását.
Videó tömörítés
A videók tömörítése elengedhetetlen része a folyamatnak, ami nagymértékben hozzájárul a folyamat zökkenőmentességéhez. Bár nem szükséges ismerni a VP8/H264 videódolgozás részleteit, a koncepció megértése segít eligibilizálni a streaming videó sebességi paramétereit, és finomhangolni a váratlan viselkedést valamint a késleltetést.
A videók tömörítése a streamelési szolgáltatások számára összetett feladat, mivel az algoritmusnak biztosítania kell, hogy a teljes kódolási idő + a hálózati átvitel ideje + a dekódolási idő a lehető legkisebb legyen. Ezenkívül a kódolási folyamatnak következetesnek és folytonosnak kell lennie. Egyes kölcsönös engedmények a kódolás során nem alkalmazhatók – például nem preferálhatjuk a hosszú kódolási időt a kisebb fájlméret és dekódolási idő érdekében, vagy használhatunk következetlen tömörítést.
A videók tömörítésének lényege, hogy eltávolítsuk a szükségtelen információkat, miközben megőrizzük a felhasználók számára elfogadható pontossági szintet. A statikus képkeretek kódolása mellett az algoritmus a jelenlegi keretet a korábbi és következő keret alapján határozza meg, így csak a közöttük lévő különbség kerül továbbításra. Ahogy a Pacman példa is mutatja, csak a differenciális pontok kerülnek átküldésre.

Videók összehasonlítása a Pacman példájánHangkodeálás
Hasonlóképpen, a hang tömörítő algoritmus is elhagyja azokat az adatokat, amelyeket az ember nem érzékelhet. Jelenleg az Opus a legjobb teljesítményű audio kodek. Az audiováltozás RTP (Real Time Transport Protocol – valós idejű forgalomátviteli protokoll) protokollon keresztül való továbbítására lett kifejlesztve. Késése alacsonyabb, mint az mp3 és aac, míg a minősége magasabb. A késleltetés általában körülbelül 5~66,5 ms.
Pion, WebRTC a Golangban
egy nyílt forráskódú projekt, amely a WebRTC-t áthúzza a Golangba. A klasszikus natív C++ WebRTC könyvtárak burkolása helyett a Pion egy natív Golang-alapú WebRTC megvalósítás, amely jobb teljesítményt, Go-integrációt, valamint verziókezelést biztosít a WebRTC protokollokhoz.
A könyvtár emellett gyors adatfolyamot biztosít számos nagyszerű, beépített modullal, kevesebb, mint egy másodperces késéssel. Saját megvalósításai vannak STUN, DTLS, SCTP és hasonlók terén, és némi kísérletezés a QUIC és WebAssembly technológiával. Ez az open-source könyvtár valóban nagyszerű tanulási forrást jelent, remek dokumentációval, hálózati protokollok megvalósításaival és klassz példákkal.
A Pion közösség, amelyet egy nagyon szenvedélyes alapító vezet, meglehetősen élénk; sok minőségi diskurzus zajlik a WebRTC-ről. Ha érdekli ez a technológia, csatlakozzon - sok új dolgot fog tanulni.
CloudRetro írása Golang nyelven

Worker megvalósítása Go nyelvenGo csatornák működés közben
A Go csatornák szép tervezése miatt az eseményfolyam és a párhuzamosság problémái jelentősen leegyszerűsödnek. Ahogy a diagramon látható, több komponens párhuzamosan működik különböző GoRoutines-ban. Minden komponens a saját állapotát kezeli és csatornákon keresztül kommunikál. A Golang kiválasztási nyilatkozata lehetővé teszi, hogy minden egyes atomáris eseményt egy korszakonként (game tick) kezeljünk. Ez azt jelenti, hogy az ilyen tervezéshez nincs szükség zárolásra. Például, amikor a felhasználó ment, szükség van a játék állapotának teljes snapshotjára. Ennek az állapotnak folyamatosan meg kell maradnia, amíg a mentés be nem fejeződik. Minden game tick során a backend csak mentési vagy belépési műveletet kezelhet, így a folyamat szálbiztos lesz.
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
Ez a Golang minta tökéletes a CrowdPlay és a Multiple Player használati esetemhez. E minta követésével minden felhasználói input egy szobában egy központi belépési csatornába integrálódik. A játék médiáit ezután minden felhasználónak a szobában kiadják. Így elérjük a játékállapot megosztását a különböző felhasználók játékmenetei között.

Szinkronizálás különböző ülések közöttA Golang hátrányai
A Golang nem tökéletes. A csatorna lassú. A Go csatorna a blokkoláshoz képest egyszerűbb módot kínál a párhuzamos és eseményalapú gyakorlatok kezelésére, de a csatorna nem biztosít a legjobb teljesítményt. A csatorna alatt bonyolult blokkolási logika húzódik meg. Ezért néhány módosítást végeztem a megvalósításon, újra alkalmazva a blokkolásokat és atomikus értékeket a csatornák teljesítményének optimalizálása érdekében.
Továbbá, a Golang garbage collector nem kézben tartott, ami miatt néha gyanúsan hosszú szünetek lépnek fel. Ez jelentősen megnehezíti a valós idejű streaming alkalmazások működését.
CGO
A projekt az open-source VP8/H264 Golang könyvtárat használja a média tömörítésére, valamint a Libretro-t a játék emulátorokhoz. Mindezek a könyvtárak egyszerűen a C könyvtár Go-ra való becsomagolásai. Néhány hátrányt felsorolnak a A problémák, amelyekkel szembesültem:
- a CGO-ban bekövetkező összeomlások elkapásának lehetetlensége, még a Golang RecoveryCrash segítségével is;
- nincs lehetőség a teljesítmény szűk keresztmetszeteinek meghatározására, amikor nem tudunk részletes problémákat felfedezni a CGO-ban.
Zárás
Elértem a célomat – megértettem a felhőalapú játék szolgáltatásokat és létrehoztam egy platformot, amely segít régi nosztalgikus játékok online játszásában a barátaimmal. Ennek a projektnek a létrehozása Pion könyvtár és a Pion közösség támogatása nélkül lehetetlen lett volna. Rendkívül hálás vagyok a folyamatos fejlesztéséért. A WebRTC és a Pion által biztosított egyszerű API-k zökkenőmentes integrálást biztosítottak. Az első koncepcióm a megfelelő héten jelent meg, annak ellenére, hogy előre nem tudtam a peer-to-peer (P2P) kapcsolatról.
A beépítés egyszerűsége ellenére a P2P streaming valóban nagyon összetett terület a számítástechnika világában. Olyan régi hálózati architektúrákkal kell foglalkoznia, mint az IP és a NAT, hogy peer-to-peer ülést hozzon létre. A projekt során rengeteg értékes tudást szereztem a hálózatokról és a teljesítmény optimalizálásáról, így mindenkinek ajánlom, hogy próbáljon P2P termékeket építeni WebRTC segítségével.
A CloudRetro minden olyan felhasználási forgatókönyvet lefed, amit retro játékosként elvártam. Mindazonáltal úgy érzem, hogy a projektben még sok terület van, amit javíthatnék, például megbízhatóbb és teljesítményesebb hálózatot létrehozni, magasabb grafikai minőséget biztosítani, vagy lehetőséget adni a felhasználók közötti játékmegosztásra. Ezen dolgozom. Kérem, figyeljék a és támogassák, ha tetszik önöknek.
Forrás: habr.com







