Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg

Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
Tarkvara kui teenus, infrastruktuur kui teenus, platvorm kui teenus, suhtlusplatvorm kui teenus, videokonverentsid kui teenus, kuidas on lood pilvemängude kui teenusega? Pilvemängude (Cloud Gaming) loomiseks on juba tehtud mitmeid katseid, näiteks Google'i hiljuti käivitatud Stadia. Stadia pole WebRTC-s uus, aga kas teised saavad WebRTC-d samamoodi kasutada?

Thanh Nguyen otsustas seda võimalust katsetada oma avatud lähtekoodiga projektis CloudRetro. CloudRetro põhineb Pionil, populaarne Go põhinev WebRTC teek (aitäh Näidatud Pioni arendusmeeskonnalt abi eest selle artikli ettevalmistamisel). Selles artiklis annab Thanh ülevaate oma projekti arhitektuurist ning räägib ka sellest, mida kasulikku ta õppis ja milliste väljakutsetega töö käigus kokku puutus.

Kanne

Eelmisel aastal, kui Google Stadiast välja kuulutas, läks see mu meelest. Idee on nii ainulaadne ja uuenduslik, et mõtlesin pidevalt, kuidas see olemasoleva tehnoloogiaga üldse võimalik on. Soov seda teemat paremini mõista ajendas mind looma avatud lähtekoodiga pilvemängust oma versiooni. Tulemus oli lihtsalt fantastiline. Allpool tahaksin jagada oma aastaga töötamise protsessi projekt.

TLDR: lühike slaidiversioon koos esiletõstmistega

Miks pilvemäng on tulevik

Usun, et Cloud Gamingust saab peagi mitte ainult mängude, vaid ka teiste arvutiteaduse valdkondade järgmine põlvkond. Pilvemäng on kliendi/serveri mudeli tipp. See mudel maksimeerib taustahaldust ja minimeerib eessüsteemi tööd, majutades mänguloogikat kaugserveris ja voogesitades pilte/heli kliendile. Server teeb rasket töötlemist, nii et klient ei ole enam riistvarapiirangute meelevallas.

Google Stadia võimaldab teil sisuliselt mängida AAA mängud (st tipptasemel kassahittide mängud) sellises liideses nagu YouTube. Sama metoodikat saab rakendada ka muude raskete võrguühenduseta rakenduste puhul, nagu operatsioonisüsteem või 2D/3D graafiline disain jne. et saaksime neid järjepidevalt käitada madala spetsifikatsiooniga seadmetes mitmel platvormil.

Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
Selle tehnoloogia tulevik: kujutage ette, kui Microsoft Windows 10 töötaks Chrome'i brauseris?

Pilvemäng on tehniliselt keeruline

Mängimine on üks neist haruldastest valdkondadest, kus on vaja pidevat ja kiiret kasutaja reageerimist. Kui lehel klõpsamisel tekib aeg-ajalt 2-sekundiline viivitus, on see vastuvõetav. Otseülekanne videovoogudes kipub mõne sekundi hilinema, kuid pakub siiski mõistlikku kasutatavust. Kui aga mäng jääb sageli 500 ms võrra maha, on see lihtsalt mängimatu. Meie eesmärk on saavutada ülimadal latentsusaeg, et sisendi ja meedia vahe oleks võimalikult väike. Seetõttu ei ole siinkohal tavapärane video voogesituse lähenemine kohaldatav.

Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
Üldine pilvemängu mall

Avatud lähtekoodiga projekt CloudRetro

Otsustasin luua pilvemängu testnäidise, et näha, kas see kõik on nii rangete võrgupiirangutega võimalik. Valisin kontseptsiooni tõestuseks Golangi, kuna see oli mulle kõige paremini tuttav keel ja sobis selle teostuse jaoks hästi paljudel muudel põhjustel, nagu hiljem avastasin. Go on lihtne ja areneb väga kiiresti; Go kanalid sobivad suurepäraselt mitmelõime haldamiseks.

Projekt CloudRetro.io on avatud lähtekoodiga pilvemänguteenus retromängude jaoks. Projekti eesmärk on tuua traditsioonilistesse retromängudesse kõige mugavam mängukogemus ja lisada mitmikmäng.
Projekti kohta saad rohkem teada siit: https://github.com/giongto35/cloud-game.

CloudRetro funktsionaalsus

CloudRetro kasutab pilvemängude võimsuse demonstreerimiseks retromänge. Mis võimaldab teil saada palju ainulaadseid mängukogemusi.

  • Mängu kaasaskantavus
    • Kohene taasesitus lehe avamisel; pole vaja alla laadida ega installida
    • Töötab mobiilibrauseris, seega pole selle käitamiseks tarkvara vaja

  • Mänguseansse saab jagada mitme seadme vahel ja salvestada pilve järgmiseks sisselogimiseks
  • Mängu saab voogesitada või seda saavad mängida mitu kasutajat korraga:
    • Crowdplay nagu TwitchPlayPokemon, ainult rohkem platvormidevahelist ja rohkem reaalajas
    • Võrguühenduseta mängud võrgus. Paljud kasutajad saavad mängida ilma võrku seadistamata. Samurai Shodowni saavad nüüd CloudRetro võrgu kaudu mängida 2 mängijat

    Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
    Mitme mängijaga võrgumängu demoversioon erinevates seadmetes

    Infrastruktuur

    Nõuded ja tehnoloogia virn

    Allpool on loetelu nõuetest, mille seadsin enne projekti alustamist.

    1. Üks mängija
    See nõue ei pruugi siinkohal tunduda liiga oluline ega ilmne, kuid see on üks minu peamisi väljavõtteid, mis võimaldab pilvemängudel traditsioonilistest voogedastusteenustest võimalikult kaugele jääda. Kui keskendume ühe mängijaga mängule, saame lahti tsentraliseeritud serverist või CDN-ist, sest me ei pea massidele voogesitama. Selle asemel, et laadida vooge üles neeldumisserverisse või edastada pakette tsentraliseeritud WebSocketi serverisse, edastatakse teenusevood otse kasutajale võrdõigusvõrgu WebRTC-ühenduse kaudu.

    2. Madala latentsusega meediavoog
    Stadia kohta lugedes näen sageli mõnes artiklis mainitud WebRTC-d. Sain aru, et WebRTC on silmapaistev tehnoloogia ja sobib suurepäraselt pilvemängudes kasutamiseks. WebRTC on projekt, mis pakub veebibrauseritele ja mobiilirakendustele reaalajas suhtlust lihtsa API kaudu. See pakub peer-to-peer-ühenduvust, on optimeeritud meediumi jaoks ja sellel on sisseehitatud standardkoodekid, nagu VP8 ja H264.

    Pidasin esmatähtsaks parima võimaliku kasutajakogemuse tagamist kvaliteetse graafika säilitamisele. Mõned kaod on algoritmis vastuvõetavad. Google Stadial on veel üks samm, mis vähendab pildi suurust serveris ja kaadreid suurendatakse enne kaaslastele edastamist kõrgemale kvaliteedile.

    3. Geograafilise marsruutimisega hajutatud infrastruktuur
    Olenemata sellest, kui optimeeritud on tihendusalgoritm ja kood, on võrk ikkagi otsustav tegur, mis mõjutab latentsust kõige rohkem. Arhitektuuril peab olema mehhanism kasutajale lähima serveri sidumiseks, et vähendada edasi-tagasi aega (RTT). Arhitektuuril peab olema 1 koordinaator ja mitu voogedastusserverit, mis on jaotatud üle kogu maailma: USA lääneosa, USA idaosa, Euroopa, Singapur, Hiina. Kõik voogedastusserverid peavad olema täielikult isoleeritud. Süsteem saab oma jaotust reguleerida, kui server võrguga liitub või sellest lahkub. Seega võimaldab suure liikluse korral täiendavate serverite lisamine horisontaalset skaleerimist.

    4. Brauseri ühilduvus
    Pilvemäng on parim siis, kui see nõuab kasutajatelt kõige vähem. See tähendab, et seda on võimalik brauseris käivitada. Brauserid aitavad muuta mängukogemuse kasutajatele võimalikult mugavaks, säästes neid tarkvara ja riistvara installimisest. Brauserid aitavad pakkuda ka platvormidevahelist funktsionaalsust mobiili- ja lauaarvutiversioonide vahel. Õnneks on WebRTC paljudes brauserites hästi toetatud.

    5. Mängu liidese ja teenuse selge eraldamine
    Ma näen pilvemänguteenust platvormina. Igaüks peaks saama platvormiga midagi ühendada. Nüüd olen integreerunud LibRetro pilvemänguteenusega, sest LibRetro pakub kaunist mänguemulaatori liidest retromängudele nagu SNES, GBA, PS.

    6. Ruumid mitme mängijaga mängimiseks, rahvahulga mängimiseks ja mänguga väliseks sidumiseks (sügav link).
    CloudRetro toetab paljusid uusi mänge, nagu CrowdPlay ja Online MultiPlayer retromängude jaoks. Kui mitu kasutajat avab erinevates arvutites sama süvalingi, näevad nad sama jooksvat mängu ja saavad sellega isegi liituda.

    Lisaks salvestatakse mängu olekud pilvesalvestusse. See võimaldab kasutajatel mängida igal ajal mis tahes muus seadmes.

    7. Horisontaalne skaleerimine
    Nagu iga SAAS tänapäeval, peab pilvemäng olema kujundatud horisontaalselt skaleeritavaks. Koordinaator-töötaja disain võimaldab teil lisada rohkem töötajaid, et teenindada rohkem liiklust.

    8. Puudub ühendus ühe pilvega
    CloudRetro infrastruktuur on majutatud erinevate piirkondade jaoks erinevatel pilveteenuse pakkujatel (Digital Ocean, Alibaba, kohandatud pakkuja). Luban käitamise Dockeri konteineris infrastruktuuri jaoks ja konfigureerin võrgusätted bash-skripti abil, et vältida ühte pilvepakkujasse lukustumist. Kombineerides selle WebRTC-s NAT Traversaliga, saame CloudRetrot paindlikult juurutada mis tahes pilveplatvormil ja isegi mis tahes kasutaja masinates.

    Arhitektuurne projekteerimine

    Töötaja: (või ülalmainitud voogedastusserver) korrutab mänge, käivitab kodeerimiskonveieri ja voogesitab kodeeritud meedia kasutajatele. Töötajate eksemplarid on laiali üle maailma ja iga töötaja saab korraga käsitleda mitut kasutajaseanssi.

    Koordinaator: vastutab uue kasutaja sidumise eest voogedastuseks sobivaima töötajaga. Koordinaator suhtleb töötajatega WebSocketi kaudu.

    Mängu oleku salvestusruum: keskne kaugmälu kõigi mänguolekute jaoks. See salvestusruum pakub olulisi funktsioone, nagu kaugsalvestamine/laadimine.

    Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
    CloudRetro tipptasemel arhitektuur

    Kohandatud skript

    Kui uus kasutaja avab CloudRetro alloleval joonisel näidatud sammudes 1 ja 2, kutsutakse koordinaator koos saadaolevate töötajate loendiga esimesele lehele. Pärast seda arvutab klient sammus 3 kõigi kandidaatide viivitused, kasutades HTTP pingipäringut. See viivituste loend saadetakse seejärel tagasi koordinaatorile, et ta saaks määrata kasutaja teenindamiseks sobivaima töötaja. 4. samm allpool loob mängu. WebRTC voogedastusühendus luuakse kasutaja ja määratud töötaja vahel.
    Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
    Kasutaja skript pärast juurdepääsu saamist

    Mis on töötaja sees

    Mängu- ja voogedastusjuhtmed salvestatakse töötaja sees isoleeritult ja vahetavad seal teavet liidese kaudu. Praegu toimub see side mälus olevate andmete edastamise kaudu Golangi kanalid samas protsessis. Järgmine eesmärk on segregatsioon, st. mängu sõltumatu käivitamine teises protsessis.

    Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
    Töötaja komponentide koostoime

    Peamised komponendid:

    • WebRTC: kliendikomponent, mis võtab vastu kasutaja sisendi ja väljastab serverist kodeeritud meediume.
    • Mängu emulaator: mängu komponent. Tänu Libretro teegile suudab süsteem mängu käitada sama protsessi sees ning sisemiselt pealt kuulata meediumi- ja sisendvoogu.
    • Mängusisesed kaadrid jäädvustatakse ja saadetakse kodeerijale.
    • Pildi/heli kodeerija: kodeerimiskonveier, mis võtab meediumikaadreid, kodeerib need taustal ja väljastab kodeeritud pilte/heli.

    Реализация

    CloudRetro tugineb oma põhitehnoloogiale WebRTC-le, nii et enne Golangi juurutamise üksikasjadesse sukeldumist otsustasin rääkida WebRTC-st endast. See on hämmastav tehnoloogia, mis on aidanud mul oluliselt saavutada andmete voogesituse alla sekundi latentsust.

    WebRTC

    WebRTC on loodud pakkuma lihtsaid API-sid kasutades kvaliteetseid peer-to-peer-ühendusi kohalikes mobiilirakendustes ja brauserites.

    NAT-i läbimine

    WebRTC on tuntud oma NAT Traversal funktsiooni poolest. WebRTC on mõeldud peer-to-peer suhtluseks. Selle eesmärk on leida kõige sobivam otsemarsruut, vältides NAT-lüüsi ja tulemüüre peer-to-peer-suhtluseks protsessi nn. ICE. Selle protsessi osana leiavad WebRTC API-d STUN-serverite abil teie avaliku IP-aadressi ja edastavad selle releeserverisse (Pöörake), kui otseühendust ei saa luua.

    Kuid CloudRetro ei kasuta seda funktsiooni täielikult ära. Selle peer-to-peer ühendused ei eksisteeri kasutajate vahel, vaid kasutajate ja pilveserverite vahel. Mudeli serveripoolel on vähem otseseid sidepiiranguid kui tavalisel kasutajaseadmel. See võimaldab teil eelnevalt avada sissetulevad pordid või kasutada otse avalikke IP-aadresse, kuna server ei ole NAT-i taga.

    Varem tahtsin muuta projekti Cloud Gamingu mängude levitamisplatvormiks. Idee oli võimaldada mängude loojatel pakkuda mänge ja voogesituse ressursse. Ja kasutajad suhtleksid teenusepakkujatega otse. Sellisel detsentraliseeritud viisil on CloudRetro vaid raamistik kolmandate osapoolte voogedastusressursside ühendamiseks kasutajatega, muutes selle skaleeritavamaks, kui seda enam ei hostita. WebRTC NAT Traversali roll on siin väga oluline, et hõlbustada võrdõigusühenduse initsialiseerimist kolmanda osapoole voogedastusressurssides, muutes looja jaoks võrguga ühenduse loomise lihtsamaks.

    Video tihendamine

    Video tihendamine on torujuhtme asendamatu osa ja aitab oluliselt kaasa sujuvale voolule. Kuigi pole vaja teada kõiki VP8/H264 videokodeeringu detaile, võib kontseptsioonide mõistmine aidata teil mõista video voogesituse kiiruse valikuid, siluda ootamatut käitumist ja kohandada latentsust.

    Video tihendamine voogedastusteenuse jaoks on keeruline, kuna algoritm peab tagama, et kogu kodeerimisaeg + võrgu edastusaeg + dekodeerimisaeg on võimalikult väike. Lisaks peab kodeerimisprotsess olema järjepidev ja pidev. Mõned kodeerimise kompromissid ei kehti – näiteks ei saa me eelistada pikki kodeerimisaegu väiksemate failisuuruste ja dekodeerimisaegade asemel või kasutada ebajärjekindlat tihendamist.

    Video tihendamise idee on kõrvaldada mittevajalikud teabekillud, säilitades samal ajal kasutajate jaoks vastuvõetava täpsuse. Lisaks üksikute staatiliste pildikaadrite kodeerimisele järeldab algoritm praeguse kaadri eelmise ja järgmise kaadri põhjal, seega saadetakse ainult nende erinevus. Nagu Pacmani näitest näha, edastatakse ainult diferentsiaalpunkte.

    Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
    Videokaadrite võrdlus Pacmani näitel

    Heli tihendamine

    Samuti jätab heli tihendamise algoritm välja andmed, mida inimesed ei taju. Opus on praegu kõige paremini toimiva helikodek. See on ette nähtud helilainete edastamiseks tellitud datagrammi protokolli, näiteks RTP (reaalajas transpordiprotokoll) kaudu. Selle latentsusaeg on madalam kui mp3 ja aac ning kvaliteet on kõrgem. Latentsusaeg on tavaliselt umbes 5–66,5 ms.

    Pion, WebRTC Golangis

    Ettur on avatud lähtekoodiga projekt, mis toob WebRTC Golangi. Tavapärase C++ WebRTC-teekide ümbrise asemel on Pion WebRTC-i Golangi algrakendus, millel on parem jõudlus, Go integratsioon ja WebRTC-protokollide versioonikontroll.

    Teek võimaldab ka voogesitust paljude suurepäraste sisseehitatud funktsioonidega, mille latentsusaeg on väiksem kui sekundis. Sellel on oma STUN, DTLS, SCTP jne rakendus. ja mõned katsed QUICi ja WebAssemblyga. See avatud lähtekoodiga teek ise on tõeliselt hea õpperessurss suurepärase dokumentatsiooni, võrguprotokolli rakenduste ja lahedate näidetega.

    Pioni kogukond, mida juhib väga kirglik looja, on üsna elav ja WebRTC teemal toimub palju kvaliteetseid arutelusid. Kui olete sellest tehnoloogiast huvitatud, liituge http://pion.ly/slack - õpid palju uusi asju.

    CloudRetro kirjutamine Golangis

    Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
    Töölise rakendamine Go-s

    Avage kanalid tegevuses

    Tänu Go kaunile kanalikujundusele on sündmuste voogesituse ja samaaegsusega seotud probleemid oluliselt lihtsustatud. Nagu diagrammil, on erinevatel GoRoutine'idel mitu paralleelset komponenti. Iga komponent haldab oma olekut ja suhtleb kanalite kaudu. Golangi valikuline väide sunnib mängus iga kord töötlema ühte aatomisündmust (mängu linnuke). See tähendab, et selle disaini jaoks pole lukustamist vaja. Näiteks kui kasutaja salvestab, on vaja mängu oleku täielikku ülevaadet. See olek peaks jääma pidevaks, sisse logides kuni salvestamise lõpetamiseni. Iga mängu linnukese ajal saab taustaprogramm hakkama ainult salvestamise või sisestustoiminguga, muutes protsessilõime turvaliseks.

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

    Sisse-/väljapuhur

    See Golangi mall sobib minu CrowdPlay ja Multiple Playeri kasutusjuhtumitega suurepäraselt. Selle mustri järgi on kõik kasutaja sisendid ühes ruumis sisse ehitatud kesksesse sissepääsukanalisse. Seejärel juurutatakse mängumeedium kõigile samas ruumis viibivatele kasutajatele. Nii saavutame mänguseisundi jaotuse erinevate kasutajate mitme mängusessiooni vahel.

    Avatud lähtekoodiga pilvemäng WebRTC-s: p2p, mitmikmäng, null latentsusaeg
    Sünkroonimine erinevate seansside vahel

    Golangi puudused

    Golang pole täiuslik. Kanal on aeglane. Võrreldes blokeerimisega on Go kanal lihtsalt lihtsam viis samaaegsete ja keermestatud sündmuste käsitlemiseks, kuid kanal ei paku parimat jõudlust. Kanali all on keeruline blokeerimisloogika. Seega tegin teostuses mõned kohandused, rakendades jõudluse optimeerimiseks kanalite asendamisel uuesti lukud ja aatomiväärtused.

    Lisaks on Golangi prügikoristaja majandamata, mis tekitab kohati kahtlaselt pikki pause. See häirib oluliselt reaalajas voogesituse rakendust.

    COG

    Projekt kasutab olemasolevat avatud lähtekoodiga Golang VP8/H264 teeki meedia tihendamiseks ja Libretrot mänguemulaatorite jaoks. Kõik need teegid on lihtsalt Go kasutades C-teegi ümbrised COG. Mõned puudused on loetletud see Dave Cheney postitus. Probleemid, millega kokku puutusin:

    • suutmatus tabada CGO-s krahhi isegi Golang RecoveryCrashiga;
    • suutmatus tuvastada jõudluse kitsaskohti, kui me ei suuda tuvastada CGO üksikasjalikke probleeme.

    Järeldus

    Täitsin oma eesmärgi mõista pilvemänguteenuseid ja luua platvormi, mis aitab mul sõpradega võrgus nostalgilisi retromänge mängida. See projekt poleks olnud võimalik ilma Pioni raamatukogu ja Pioni kogukonna toetuseta. Olen ülimalt tänulik selle intensiivse arendamise eest. WebRTC ja Pioni pakutavad lihtsad API-d tagasid sujuva integratsiooni. Minu esimene kontseptsiooni tõend ilmus samal nädalal, kuigi mul polnud eelteadmisi võrdõigussuhtlusest (P2P).

    Vaatamata integreerimise lihtsusele on P2P voogesitus arvutiteaduses tõepoolest väga keeruline valdkond. Peer-to-peer seansi loomiseks peab ta tegelema pikaajaliste võrguarhitektuuride (nt IP ja NAT) keerukusega. Selle projekti kallal töötades sain palju väärtuslikke teadmisi võrgu loomise ja jõudluse optimeerimise kohta, seega julgustan kõiki proovima WebRTC abil P2P-tooteid luua.

    CloudRetro pakub kõiki kasutusjuhtumeid, mida ootasin oma retromänguri vaatenurgast. Siiski arvan, et projektis on palju valdkondi, mida saan parandada, näiteks võrgu töökindluse ja jõudlusega muutmine, kvaliteetsema mängugraafika pakkumine või mängude jagamise võimalus kasutajate vahel. Ma töötan selle nimel kõvasti. Palun järgige projekt ja toetage seda, kui teile meeldib.

Allikas: www.habr.com

Lisa kommentaar