Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency

Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
Software as tsjinst, ynfrastruktuer as tsjinst, platfoarm as tsjinst, kommunikaasjeplatfoarm as tsjinst, fideokonferinsjes as tsjinst, hoe sit it mei wolkgaming as tsjinst? D'r binne al ferskate pogingen west om wolkgaming (Cloud Gaming) te meitsjen, lykas Stadia, koartlyn lansearre troch Google. Stadia net nij foar WebRTC, mar kinne oaren WebRTC op deselde wize brûke?

Thanh Nguyen besleat dizze kâns te testen op syn iepen boarne-projekt CloudRetro. CloudRetro is basearre op Pion, populêr WebRTC-bibleteek basearre op Go (tank Weromjûn fan it Pion-ûntwikkelingsteam foar har help by it tarieden fan dit artikel). Yn dit artikel jout Thanh in oersjoch fan 'e arsjitektuer fan syn projekt, en fertelt ek oer hokker nuttige dingen hy learde en hokker útdagings hy tsjinkaam tidens syn wurk.

Ynlieding

Ferline jier, doe't Google Stadia oankundige, blies it myn geast. It idee is sa unyk en ynnovatyf dat ik my hieltyd ôffrege hoe't dit sels mooglik wie mei besteande technology. De winsk om dit ûnderwerp better te begripen frege my om myn eigen ferzje fan in iepen-boarne-wolkspultsje te meitsjen. It resultaat wie gewoan fantastysk. Hjirûnder wol ik it proses fan wurkjen oan myn jier diele projekt.

TLDR: koarte slide ferzje mei hichtepunten

Wêrom wolk gaming is de takomst

Ik leau dat Cloud Gaming ynkoarten de folgjende generaasje sil wurde fan net allinich gaming, mar ek oare gebieten fan kompjûterwittenskip. Wolkgaming is it hichtepunt fan it client-/servermodel. Dit model maksimalisearret backend-behear en minimalisearret frontend-wurk troch it hostjen fan spiellogika op in tsjinner op ôfstân en streaming fan ôfbyldings / audio nei de kliïnt. De tsjinner docht de swiere ferwurking sadat de kliïnt net langer oan 'e genede is fan hardwarebeheiningen.

Google Stadia lit jo yn wêzen spielje AAA games (dus high-end blockbuster games) op in ynterface lykas YouTube. Deselde metodyk kin tapast wurde op oare swiere offline applikaasjes lykas bestjoeringssysteem of 2D / 3D grafysk ûntwerp, ensfh. sadat wy se konsekwint kinne útfiere op apparaten mei lege spesifikaasjes oer meardere platfoarms.

Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
De takomst fan dizze technology: Stel jo foar as Microsoft Windows 10 rûn op 'e Chrome-blêder?

Cloud-gaming is technysk útdaagjend

Gaming is ien fan dy seldsume gebieten dêr't konstante, flugge brûkersantwurd is fereaske. As wy soms in fertraging fan 2 sekonden tsjinkomme by it klikken op in side, is dit akseptabel. Live fideostreamen hawwe de neiging om in pear sekonden te lizzen, mar biede dochs in ridlike brûkberens. As it spultsje lykwols faak mei 500ms bliuwt, is it gewoan net te spieljen. Us doel is om ekstreem lege latency te berikken, sadat it gat tusken input en media sa lyts mooglik is. Dêrom is de tradisjonele oanpak fan fideostreaming hjir net fan tapassing.

Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
Algemiene Cloud Game Template

Iepen boarne projekt CloudRetro

Ik besleat om in testmonster fan in wolkespultsje te meitsjen om te sjen oft dit alles mooglik wie mei sokke strakke netwurkbeperkingen. Ik keas Golang foar it proof of concept omdat it de taal wie dy't ik it meast bekend wie en om in protte oare redenen goed geskikt wie foar dizze ymplemintaasje, lykas ik letter ûntduts. Go is ienfâldich en ûntwikkelet hiel fluch; Kanalen yn Go binne geweldich foar it behearen fan multithreading.

It projekt CloudRetro.io is in iepen boarne cloud-gamingtsjinst foar retro-gaming. It doel fan it projekt is om de meast noflike gamingûnderfining te bringen nei tradisjonele retro-spultsjes en multiplayer ta te foegjen.
Jo kinne hjir mear leare oer it projekt: https://github.com/giongto35/cloud-game.

CloudRetro funksjonaliteit

CloudRetro brûkt retro-spultsjes om de krêft fan cloud-gaming te demonstrearjen. Wat kinne jo krije in protte unike gaming ûnderfinings.

  • Portabiliteit fan it spul
    • Daliks ôfspieljen by it iepenjen fan de side; gjin download of ynstallaasje nedich
    • Wurket yn in mobile browser, dus gjin software is nedich om it út te fieren

  • Spultsje sesjes kinne wurde dield oer meardere apparaten en opslein yn 'e wolk foar de folgjende kear as jo ynlogge
  • It spultsje kin wurde streamd, of it kin wurde spile troch ferskate brûkers tagelyk:
    • Crowdplay lykas TwitchPlayPokemon, allinich mear cross-platform en mear real-time
    • Offline spultsjes online. In protte brûkers kinne spylje sûnder it opsetten fan in netwurk. Samurai Shodown kin no wurde spile troch 2 spilers oer it CloudRetro netwurk

    Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
    Demo-ferzje fan online multiplayer-spiel op ferskate apparaten

    Ynfrastruktuer

    Easken en technology stack

    Hjirûnder is in list mei easken dy't ik stel foardat it projekt begon.

    1. Ien spiler
    Dizze eask liket hjir miskien net te wichtich of fanselssprekkend, mar it is ien fan myn wichtige takeaways, it lit wolkgaming sa fier mooglik fan tradisjonele streamingtsjinsten fuort bliuwe. As wy rjochtsje op in single-player-spiel, kinne wy ​​​​in sintralisearre server as CDN kwytreitsje, om't wy net hoege te streamen nei de massa. Yn stee fan in upload streamen nei in sink tsjinner of trochjaan pakketten nei in sintralisearre WebSocket tsjinner, tsjinst streamen wurde levere direkt oan de brûker fia in peer-to-peer WebRTC ferbining.

    2. Low latency media stream
    As ik oer Stadia lêze, sjoch ik faaks dat WebRTC yn guon artikels neamd wurdt. Ik realisearre dat WebRTC in treflike technology is en perfekt is foar gebrûk yn wolkgaming. WebRTC is in projekt dat webbrowsers en mobile applikaasjes mei real-time kommunikaasje leveret fia in ienfâldige API. It leveret peer-to-peer-ferbining, is optimalisearre foar media, en hat standert codecs ynboud lykas VP8 en H264.

    Ik prioritearre it garandearjen fan de bêste mooglik brûkersûnderfining boppe it behâld fan grafiken fan hege kwaliteit. Guon ferliezen binne akseptabel yn it algoritme. Google Stadia hat in ekstra stap om de ôfbyldingsgrutte op 'e tsjinner te ferminderjen, en frames wurde opskaald nei in hegere kwaliteit foardat se wurde oerdroegen oan peers.

    3. Ferspraat ynfrastruktuer mei geografyske routing
    Nettsjinsteande hoe optimalisearre it kompresjealgoritme en koade binne, it netwurk is noch altyd de beslissende faktor dy't it measte bydraacht oan latency. De arsjitektuer moat in meganisme hawwe om de tsjinner it tichtst by de brûker te koppelen om rûnreistiid (RTT) te ferminderjen. De arsjitektuer moat 1 koördinator hawwe en ferskate streamingservers ferspraat oer de hiele wrâld: US West, US East, Europe, Singapore, China. Alle streamingservers moatte folslein isolearre wurde. It systeem kin har ferdieling oanpasse as in tsjinner by it netwurk komt of ferlit. Sa, mei grut ferkear, it tafoegjen fan ekstra servers soarget foar horizontale skaalfergrutting.

    4. Browser komptabiliteit
    Cloud-gaming is op syn bêst as it it minste fereasket fan brûkers. Dit betsjut dat it mooglik is om te rinnen yn in browser. Browsers helpe de gamingûnderfining sa noflik mooglik te meitsjen foar brûkers, en bewarje se fan it ynstallearjen fan software en hardware. Browsers helpe ek cross-platform-funksjonaliteit te leverjen tusken mobile en buroblêdferzjes. Gelokkich wurdt WebRTC goed stipe oer in ferskaat oan browsers.

    5. Dúdlike skieding fan it spul ynterface en tsjinst
    Ik sjoch de wolk gaming tsjinst as in platfoarm. Elkenien moat alles kinne ferbine mei it platfoarm. No haw ik yntegrearre Libretro mei wolk gaming tsjinst omdat LibRetro biedt in prachtige spultsje emulator ynterface foar retro games lykas SNES, GBA, PS.

    6. Keamers foar multiplayer, crowd play en eksterne keppeling (djippe keppeling) mei it spultsje
    CloudRetro stipet in protte nije gameplays lykas CrowdPlay en Online MultiPlayer foar retro-spultsjes. As ferskate brûkers deselde djippe keppeling op ferskate kompjûters iepenje, sille se itselde spultsje rinnen sjen en kinne se sels meidwaan.

    Boppedat, spultsje steaten wurde opslein yn wolk opslach. Hjirmei kinne brûkers op elk momint trochgean te spyljen op elk oar apparaat.

    7. Horizontale skaalfergrutting
    Lykas elke SAAS tsjintwurdich, moat cloud-gaming wurde ûntworpen om horizontaal skaalber te wêzen. It ûntwerp fan koördinator-arbeider kinne jo mear arbeiders tafoegje om mear ferkear te tsjinjen.

    8. Gjin ferbining mei ien wolk
    CloudRetro's ynfrastruktuer wurdt host op ferskate wolkproviders (Digital Ocean, Alibaba, oanpaste provider) foar ferskate regio's. Ik aktivearje it rinnen yn in Docker-kontener foar de ynfrastruktuer en konfigurearje netwurkynstellingen mei in bash-skript om foar te kommen dat se opsletten wurde yn ien wolkprovider. Troch dit te kombinearjen mei NAT Traversal yn WebRTC, kinne wy ​​​​de fleksibiliteit hawwe om CloudRetro yn te setten op elk wolkplatfoarm en sels op masines fan elke brûker.

    Arsjitektoanysk ûntwerp

    Wurkster: (as de hjirboppe neamde streamingtsjinner) fermannichfâldicht de spultsjes, rint de kodearringpipeline, en streamt de kodearre media nei brûkers. Worker eksimplaren wurde ferspraat oer de hiele wrâld, en elke arbeider kin omgean meardere brûkers sesjes tagelyk.

    Koördinator: is ferantwurdlik foar it koppelen fan de nije brûker mei de meast geskikte wurker foar streaming. De koördinator ynteraksje mei arbeiders fia WebSocket.

    Game state opslach: sintrale opslach op ôfstân foar alle spultsje steaten. Dizze opslach leveret wichtige funksjes lykas opslaan / laden op ôfstân.

    Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
    Top-nivo arsjitektuer fan CloudRetro

    Oanpaste Skript

    As in nije brûker CloudRetro iepenet yn stappen 1 en 2 werjûn yn 'e ôfbylding hjirûnder, wurdt de koördinator tegearre mei de list mei beskikbere arbeiders frege nei de earste side. Hjirnei berekkent de kliïnt yn stap 3 de fertragingen foar alle kandidaten mei in HTTP-ping-fersyk. Dizze list mei fertragingen wurdt dan weromstjoerd nei de koördinator, sadat hy de meast geskikte arbeider kin bepale om de brûker te tsjinjen. Stap 4 hjirûnder makket it spultsje. In WebRTC-streamingferbining wurdt oprjochte tusken de brûker en de tawiisde arbeider.
    Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
    Meidogger skript nei it krijen fan tagong

    Wat is binnen de arbeider

    Game en streaming pipelines wurde opslein binnen de arbeider yn isolemint en útwikselje ynformaasje dêr fia de ynterface. Op it stuit wurdt dizze kommunikaasje útfierd troch it oerdragen fan gegevens yn it ûnthâld fia Golang kanalen yn itselde proses. It folgjende doel is segregaasje, d.w.s. ûnôfhinklike lansearring fan it spul yn in oar proses.

    Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
    Ynteraksje fan arbeiderskomponinten

    Haadkomponinten:

    • WebRTC: in client komponint dat akseptearret brûkersynput en útfier kodearre media út de tsjinner.
    • Spultsje emulator: spultsje komponint. Mei tank oan de Libretro-bibleteek is it systeem yn steat om it spultsje yn itselde proses út te fieren en ynterne media en ynfierstream te ûnderskeppen.
    • Frames yn it spultsje wurde fêstlein en stjoerd nei de encoder.
    • Ofbylding/audio-koder: in kodearring pipeline dy't nimt media frames, kodearret se op 'e eftergrûn, en útfier kodearre ôfbyldings / audio.

    Ymplemintaasje

    CloudRetro fertrout op WebRTC as har rêchbonketechnology, dus foardat ik yn 'e details fan' e Golang-ymplemintaasje dûke, besleat ik oer WebRTC sels te praten. Dit is geweldige technology dy't my sterk holpen hat by it berikken fan sub-sekonde latency foar streaminggegevens.

    WebRTC

    WebRTC is ûntworpen om peer-to-peer-ferbiningen fan hege kwaliteit te leverjen op native mobile apps en browsers mei ienfâldige API's.

    NAT Traversal

    WebRTC is bekend om syn NAT Traversal-funksjonaliteit. WebRTC is ûntworpen foar peer-to-peer-kommunikaasje. It doel is om de meast geskikte direkte rûte te finen, NAT-poarten en firewalls te foarkommen foar peer-to-peer-kommunikaasje fia in proses neamd IIS. As ûnderdiel fan dit proses fine de WebRTC API's jo iepenbiere IP-adres mei STUN-tsjinners en stjoere it troch nei de estafetteserver (BOCHT) as in direkte ferbining net kin wurde oprjochte.

    CloudRetro brûkt dizze funksje lykwols net folslein. De peer-to-peer-ferbiningen besteane net tusken brûkers, mar tusken brûkers en wolkservers. De serverkant fan it model hat minder direkte kommunikaasjebeperkingen dan in typysk brûkersapparaat. Hjirmei kinne jo ynkommende havens foarôf iepenje of iepenbiere IP-adressen direkt brûke, om't de tsjinner net efter NAT is.

    Earder woe ik it projekt omsette yn in spielferdielingsplatfoarm foar Cloud Gaming. It idee wie om spultsje-skeppers te tastean spultsjes en streamingboarnen te leverjen. En brûkers soene direkt ynteraksje mei oanbieders. Op dizze desintralisearre manier is CloudRetro gewoan in ramt foar it ferbinen fan streamingboarnen fan tredden oan brûkers, wêrtroch it skalberber is as it net mear wurdt hosted. De rol fan WebRTC NAT Traversal hjir is heul wichtich om inisjalisaasje fan peer-to-peer-ferbining te fasilitearjen op streamingboarnen fan tredden, wêrtroch it makliker is foar de skepper om te ferbinen mei it netwurk.

    Video kompresje

    Fideokompresje is in ûnmisber diel fan 'e pipeline en draacht in protte by oan in glêde stream. Hoewol it net nedich is om elk detail fan VP8 / H264-fideokodearring te kennen, kin it begripen fan 'e begripen jo helpe om opsjes foar streamingfideosnelheid te begripen, ûnferwacht gedrach te debuggen en latency oan te passen.

    It komprimearjen fan fideo foar in streamingtsjinst is útdaagjend, om't it algoritme moat soargje dat de totale kodearringstiid + netwurktransmissiontiid + dekodearjende tiid sa leech mooglik is. Derneist moat it kodearringproses konsekwint en kontinu wêze. Guon kodearring kompromissen binne net fan tapassing - wy kinne bygelyks lange kodearringstiden net favorisearje oer lytsere triemgrutte en dekodearjen, of inkonsistente kompresje brûke.

    It idee efter fideokompresje is om ûnnedige stikken ynformaasje te eliminearjen, wylst in akseptabel nivo fan krektens foar brûkers behâldt. Neist it kodearjen fan yndividuele statyske byldframes, lei it algoritme it hjoeddeistige frame ôf fan 'e foarige en folgjende, sadat allinich har ferskil wurdt ferstjoerd. Lykas út it foarbyld mei Pacman te sjen is, wurde allinich differinsjaalpunten oerdroegen.

    Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
    Fergeliking fan fideoframes mei Pacman as foarbyld

    Audio kompresje

    Likemin ferlit it audiokompresjealgoritme gegevens dy't net troch minsken kinne wurde waarnommen. Opus is op it stuit de bêste prestearjende audio-codec. It is ûntworpen om in audiowelle oer te stjoeren oer in bestelde datagramprotokol lykas RTP (Real Time Transport Protocol). De latency is leger dan mp3 en aac, en de kwaliteit is heger. De latency is normaal om 5 ~ 66,5ms.

    Pion, WebRTC yn Golang

    Pion is in iepen boarne projekt dat WebRTC nei Golang bringt. Ynstee fan 'e gewoane omslach fan native C++ WebRTC-biblioteken, is Pion in native Golang-ymplemintaasje fan WebRTC mei bettere prestaasjes, Go-yntegraasje en ferzjekontrôle op WebRTC-protokollen.

    De bibleteek makket ek streaming mooglik mei in protte geweldige ynboude mei sub-sekonde latency. It hat in eigen ymplemintaasje fan STUN, DTLS, SCTP, ensfh. en guon eksperiminten mei QUIC en WebAssembly. Dizze iepen boarne bibleteek sels is in echt goede learboarne mei poerbêste dokumintaasje, ymplemintaasje fan netwurkprotokol, en koele foarbylden.

    De Pion-mienskip, laat troch in heul hertstochtlike skepper, is frij libbendich, mei in protte kwaliteitsdiskusjes oer WebRTC. As jo ​​ynteressearre binne yn dizze technology, join http://pion.ly/slack - jo sille in protte nije dingen leare.

    CloudRetro skriuwe yn Golang

    Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
    Utfiering fan in arbeider yn Go

    Gean Channels yn aksje

    Mei tank oan it prachtige kanaalûntwerp fan Go binne de problemen fan streaming fan eveneminten en tagelyk sterk ferienfâldige. Lykas yn it diagram hawwe ferskate GoRoutines meardere komponinten dy't parallel rinne. Elke komponint beheart syn steat en kommunisearret fia kanalen. De selektive bewearing fan Golang twingt ien atoombarren elke kear yn it spul te ferwurkjen (spultsje tick). Dit betsjut dat gjin beskoatteljen is nedich foar dit ûntwerp. Bygelyks, as in brûker opslacht, is in folsleine momintopname fan 'e spielstatus fereaske. Dizze tastân moat kontinu bliuwe, ynlogge oant it opslaan is foltôge. Tidens eltse wedstriid tick, de backend kin allinnich omgean in opslach of ynfier operaasje, wêrtroch't it proses tried feilich.

    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

    Dit Golang-sjabloan past perfekt by myn CrowdPlay en Multiple Player-gebrûk. Nei dit patroan binne alle brûkersynputen yn ien keamer boud yn it sintrale yngongskanaal. Spultsjemedia wurdt dan ynset foar alle brûkers yn deselde keamer. Op dizze manier berikke wy de ferdieling fan 'e spielstatus tusken ferskate spielsesjes fan ferskate brûkers.

    Iepenboarne wolkgaming op WebRTC: p2p, multiplayer, nul latency
    Syngronisaasje tusken ferskate sesjes

    Neidielen fan Golang

    Golang is net perfekt. It kanaal is stadich. Yn ferliking mei blokkearjen is Go-kanaal gewoan in maklikere manier om tagelyk en threaded eveneminten te behanneljen, mar it kanaal leveret net de bêste prestaasje. D'r is komplekse blokkearjende logika ûnder it kanaal. Dat ik haw wat oanpassingen makke oan 'e ymplemintaasje, slûzen en atomêre wearden opnij tapasse by it ferfangen fan kanalen om prestaasjes te optimalisearjen.

    Derneist is de jiskefet yn Golang net beheard, wat soms fertochte lange pauzes soarget. Dit interfereart sterk mei de real-time streamingapplikaasje.

    CGO

    It projekt brûkt de besteande iepen boarne Golang VP8 / H264-bibleteek foar mediakompresje en Libretro foar spultsje-emulators. Al dizze bibleteken binne gewoan wrappers fan 'e C-bibleteek yn Go brûke CGO. Guon fan 'e neidielen wurde neamd yn dizze post troch Dave Cheney. Problemen dy't ik tsjinkaam:

    • ûnfermogen om in crash yn CGO te fangen, sels mei Golang RecoveryCrash;
    • mislearjen fan knyppunten foar prestaasjes as wy net by steat binne om detaillearre problemen yn CGO te detektearjen.

    konklúzje

    Ik berikte myn doel om wolk-gamingtsjinsten te begripen en in platfoarm te meitsjen dat my helpt nostalgyske retro-spultsjes mei myn freonen online te spyljen. Dit projekt soe net mooglik west hawwe sûnder de Pion-bibleteek en de stipe fan de Pion-mienskip. Ik bin tige tankber foar har yntinsive ûntwikkeling. De ienfâldige API's levere troch WebRTC en Pion soarge foar naadleaze yntegraasje. Myn earste proof of concept waard deselde wike frijlitten, ek al hie ik gjin foarkennis fan peer-to-peer (P2P) kommunikaasje.

    Nettsjinsteande it gemak fan yntegraasje, is P2P-streaming yndie in heul kompleks gebiet yn kompjûterwittenskip. Se hat te krijen mei de kompleksiteit fan langsteande netwurkarsjitektueren lykas IP en NAT om in peer-to-peer-sesje te meitsjen. Wylst ik oan dit projekt wurke, krige ik in protte weardefolle kennis oer netwurking en prestaasjesoptimalisaasje, dus ik stimulearje elkenien om te besykjen P2P-produkten te bouwen mei WebRTC.

    CloudRetro foldocht oan alle gebrûksgefallen dy't ik ferwachte fan myn perspektyf as retro-gamer. Ik tink lykwols dat d'r in protte gebieten yn it projekt binne dy't ik ferbetterje kin, lykas it meitsjen fan it netwurk betrouberer en performanter, it leverjen fan spultsje-grafiken fan hegere kwaliteit, of de mooglikheid om spultsjes te dielen tusken brûkers. Ik wurkje hjir hurd oan. Folgje asjeblyft projekt en stypje it as jo it leuk fine.

Boarne: www.habr.com

Add a comment