{"id":89303,"date":"2020-07-22T01:42:30","date_gmt":"2020-07-21T23:42:30","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency"},"modified":"2020-07-22T01:42:30","modified_gmt":"2020-07-21T23:42:30","slug":"oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency","title":{"rendered":"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/Voximplant\/blog\/511626\/\"><img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/22dbf7665d7fded15671d98a2afe599b.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\nKot delovna oblika, infrastruktura kot storitev, platforma kot storitev, komunikacijska platforma kot storitev, video konference kot storitev, kaj pa obla\u010dne igre kot storitev? Na podro\u010dju obla\u010dnih iger (Cloud Gaming) je bilo \u017ee nekaj poskusov, na primer Stadia, ki jo je nedavno zagnal Google. <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/avtlQeaxd_I?t=440\">ni novinec v WebRTC<\/a><\/noindex>, vendar lahko tudi drugi uporabijo WebRTC na enak na\u010din?<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Thanh Nguyen se je odlo\u010dil preveriti to mo\u017enost s svojim odprtokodnim projektom CloudRetro. CloudRetro temelji na Pionu, <noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/webrtc-open-source-most-popular\/\">popularni<\/a><\/noindex> WebRTC knji\u017enici, ki temelji na Go (hvala <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Sean-Der\">Shonu<\/a><\/noindex> iz Pionove razvojne skupine za pomo\u010d pri pripravi tega \u010dlanka). V tem \u010dlanku Thanh predstavi arhitekturo svojega projekta in deli, kaj je koristnega izvedel ter s katerimi izzivi se je soo\u010dil med delom.<\/p>\n<h2>Uvod<\/h2>\n<p>\nLani, ko je Google napovedal Stadia, sem bil popolnoma navdu\u0161en. Ideja je tako edinstvena in inovativna, da sem se nenehno spra\u0161eval, kako je to sploh mogo\u010de s trenutno tehnologijo. \u017delja po bolj\u0161i razumljivosti te tematike me je spodbudila, da sem ustvaril svojo razli\u010dico odprtokodnih obla\u010dnih iger. Rezultat je bil enostavno fantasti\u010den. Spodaj bi rad delil proces dela na mojem enoletnem <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">projekat<\/a><\/noindex>.<\/p>\n<p><i>TLDR: kratka razli\u010dica s klju\u010dnimi to\u010dkami<\/i><\/p>\n<h3>Zakaj so obla\u010dne igre prihodnost<\/h3>\n<p>\nVerjamem, da bo Cloud Gaming kmalu nova generacija ne le iger, temve\u010d tudi drugih podro\u010dij ra\u010dunalni\u0161tva. Obla\u010dne igre so vrhunec modela odjemalec\/server. Ta model maksimira upravljanje s \u200b\u200bzadnjim delom in minimizira delo sprednjega dela s tem, da se igralna logika nahaja na oddaljenem stre\u017eniku, slike\/avdio pa se pretakajo strankam. Stre\u017enik izvaja zahtevno obdelavo, zato odjemalec ni ve\u010d odvisen od strojne opreme.<\/p>\n<p>Google Stadia prakti\u010dno omogo\u010da igranje <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/AAA_(%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%BD%D1%8B%D0%B5_%D0%B8%D0%B3%D1%80%D1%8B)\">AAA iger<\/a><\/noindex> (tj. visokoprora\u010dunskih blockbuster iger) v vmesniku podobnem YouTubu. Enaka metoda se lahko uporabi tudi za druge zahtevne namizne aplikacije, kot so operacijski sistemi ali 2D\/3D grafi\u010dni dizajn itd., da jih lahko zanesljivo za\u017eenemo na napravah z nizkimi tehni\u010dnimi specifikacijami na razli\u010dnih platformah.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/d6ca3e47db5c8e3d9880b304cc3be33b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nPrihodnost te tehnologije: si predstavljate, \u010de bi Microsoft Windows 10 deloval v brskalniku Chrome?<\/p>\n<h3>Obla\u010dne igre so tehni\u010dno zahtevne.<\/h3>\n<p>\nIgra je jedno od onih retkih podru\u010dja gde je potrebna stalna brza reakcija korisnika. Ako se povremeno suo\u010dimo sa ka\u0161njenjem od 2 sekunde prilikom klika na stranici, to je prihvatljivo. Video strimovi u\u017eivo obi\u010dno kasne nekoliko sekundi, ali ipak nude dovoljno udobnosti. Ipak, ako igra \u010desto kasni 500 ms, jednostavno je nemogu\u0107e igrati. Na\u0161 cilj je posti\u0107i izuzetno nisku latenciju, tako da prekid izme\u0111u unosa i medija bude \u0161to manji. Stoga tradicionalni pristup striming videu ovde nije primenjiv.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/d73765a3c9277c026f407883e1091473.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nOp\u0161ti \u0161ablon cloud gaming-a<\/p>\n<h2>Open source projekat CloudRetro<\/h2>\n<p>\nOdlu\u010dio sam da napravim probni uzorak cloud gaming-a kako bih proverio da li je sve to mogu\u0107e pod ovim strogo mre\u017enim ograni\u010denjima. Za proveru koncepta izabrao sam Golang, jer je to jezik koji mi je najpoznatiji i dobro se uklapa za ovu implementaciju iz mnogih drugih razloga, kako se kasnije pokazalo. Go je jednostavan i brzo se razvija; kanali u Go-u su odli\u010dni za upravljanje vi\u0161estrukim nitima.<\/p>\n<p>Projekt <noindex><a rel=\"nofollow\" href=\"http:\/\/cloudretro.io\/\">CloudRetro.io<\/a><\/noindex> \u2013 cloud gaming servis sa otvorenim izvorom za retro igre. Cilj projekta je da unese najudobnije iskustvo igranja u tradicionalne retro igre i dodati multiplayer.<br \/>\nDetaljnije informacije o projektu mo\u017eete prona\u0107i ovde: <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">https:\/\/github.com\/giongto35\/cloud-game<\/a><\/noindex>.<\/p>\n<h3>Funkcionalnost CloudRetro<\/h3>\n<p>\nKako bi se demonstrirala sva mo\u0107 cloud gaming-a, CloudRetro koristi retro igre. To omogu\u0107ava dobijanje niza jedinstvenih igra\u010dkih iskustava.<\/p>\n<ul>\n<li>Pristupa\u010dnost igre\n<ul>\n<li>Trenutno reprodukovanje prilikom otvaranja stranice; preuzimanje i instalacija nisu potrebni<\/li>\n<li>Radi u mobilnom pretra\u017eiva\u010du, tako da nije potrebno nikakvo softversko re\u0161enje za pokretanje<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>Sesije igranja mogu\u0107e je zajedni\u010dki koristiti na vi\u0161e ure\u0111aja i \u010duvati u oblaku za slede\u0107i pristup<\/li>\n<li>Igru je mogu\u0107e streamovati, ili mogu instantno igrati nekoliko korisnika:\n<ul>\n<li>Crowdplay tipa TwitchPlayPokemon, samo \u0161to je vi\u0161e multiplatformski i vi\u0161e u realnom vremenu<\/li>\n<li>Offline igre online. Mogu igrati mnogi korisnici bez pode\u0161avanja mre\u017ee. U Samurai Shodown sada mogu igrati 2 igra\u010da putem CloudRetro mre\u017ee<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/bdc715971755d669a026f830ce888520.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDemo verzija multiplayer online igre na razli\u010ditim ure\u0111ajima<\/p>\n<h2>Infrastruktura<\/h2>\n<p><\/p>\n<h3>Zahtevi i tehnologije<\/h3>\n<p>\nIspod je lista zahteva koje sam postavio pre nego \u0161to sam zapo\u010deo projekat.<\/p>\n<p><b>1. Eden igralec<\/b><br \/>\nTo zahteva se lahko zdi nepomembna in o\u010ditna, vendar je to ena izmed mojih klju\u010dnih ugotovitev, ki omogo\u010da, da se obla\u010dne igre kar se da oddaljijo od tradicionalnih streaming storitev. \u010ce se osredoto\u010dimo na enojne igralce, se lahko izognemo centraliziranemu stre\u017eniku ali CDN, ker ni potrebno streamati mno\u017eicam. Namesto da bi nalagali tokove na obremenitveni stre\u017enik ali prena\u0161ali pakete na centralizirani WebSocket stre\u017enik, se storitveni tokovi prena\u0161ajo neposredno uporabniku prek povezave Peer-to-Peer WebRTC.<\/p>\n<p><b>2. Medijski tok z nizko zamudo<\/b><br \/>\nKo berem o Stadii, pogosto naletim na omembo WebRTC v nekaterih \u010dlankih. Spoznal sem, da je WebRTC izjemna tehnologija, ki je zelo primerna za obla\u010dne igre. WebRTC je projekt, ki zagotavlja komunikacijo v realnem \u010dasu za spletne brskalnike in mobilne aplikacije preko preprostega API-ja. Omogo\u010da peer-to-peer povezavo, optimizirano za medije, in ima vgrajene standardne kodeke, kot sta VP8 in H264.<\/p>\n<p>Dal sem prednost zagotavljanju \u010dim bolj udobne izku\u0161nje uporabnikov pred ohranjanjem visoke kakovosti grafike. V algoritmu so dopustne nekatere izgube. V Google Stadii je dodaten korak za zmanj\u0161anje velikosti slike na stre\u017eniku, in sli\u010dice se pove\u010dajo na vi\u0161jo kakovost pred prenosom peer-u.<\/p>\n<p><b>3. Distribucijska infrastruktura z geografsko usmeritvijo<\/b><br \/>\nNe glede na to, kako optimiziran je algoritem za stiskanje in koda, je omre\u017eje \u0161e vedno odlo\u010dilni dejavnik, ki najbolj vpliva na zamudo. Arhitektura mora imeti mehanizem za povezovanje najbli\u017ejega stre\u017enika uporabniku za zmanj\u0161anje \u010dasa prenosa (RTT). Arhitektura mora imeti 1 koordinatorski stre\u017enik in ve\u010d streaming stre\u017enikov, razporejenih po svetu: Zahod ZDA, Vzhod ZDA, Evropa, Singapur, Kitajska. Vsi streaming stre\u017eniki morajo biti popolnoma izolirani. Sistem lahko prilagodi svoje razporejanje, ko se stre\u017enik pridru\u017ei ali izklopi iz omre\u017eja. Tako pri ve\u010dji obremenitvi dodajanje dodatnih stre\u017enikov omogo\u010da horizontalno raz\u0161iritev.<\/p>\n<p><b>4. Zdru\u017eljivost brskalnika<\/b><br \/>\nObla\u010dne igre se najbolje prikazuju kada od korisnika zahtevaju minimum. To zna\u010di da postoji mogu\u0107nost pokretanja u pretra\u017eiva\u010du. Pretra\u017eiva\u010di poma\u017eu da se proces igranja u\u010dini \u0161to udobnijim za korisnike, osloba\u0111aju\u0107i ih od instalacije softverske i hardverske opreme. Pretra\u017eiva\u010di tako\u0111e omogu\u0107avaju me\u0111usobnu kompatibilnost mobilnih i desktop verzija. Na sre\u0107u, WebRTC se odli\u010dno podr\u017eava u razli\u010ditim pretra\u017eiva\u010dima.<\/p>\n<p><b>5. Jasna podela izme\u0111u korisni\u010dkog interfejsa i usluge<\/b><br \/>\nSmatram da je usluga obla\u010dnih igara platforma. Svako treba da ima mogu\u0107nost povezivanja bilo \u010dega s platformom. Trenutno sam integrisao <noindex><a rel=\"nofollow\" href=\"http:\/\/LibRetro\">LibRetro<\/a><\/noindex> s uslugom obla\u010dnih igara, jer LibRetro nudi lep interfejs emulatora za retro igre kao \u0161to su SNES, GBA, PS.<\/p>\n<p><b>6. Sobe za vi\u0161e igra\u010da, crowd play i eksterno povezivanje (deep-link) s igrom<\/b><br \/>\nCloudRetro podr\u017eava brojne nove na\u010dine igranja, kao \u0161to su CrowdPlay i Online MultiPlayer za retro igre. Ako vi\u0161e korisnika otvori isti deep-link na razli\u010ditim ra\u010dunarima, vide\u0107e istu pokrenutu igru i \u010dak \u0107e mo\u0107i da joj se pridru\u017ee.<\/p>\n<p>\u0160tavi\u0161e, stanja igara se \u010duvaju u obla\u010dnom skladi\u0161tu. To omogu\u0107ava korisnicima da nastave igru u bilo kom trenutku na bilo kojem drugom ure\u0111aju.<\/p>\n<p><b>7. Horizontalno skaliranje<\/b><br \/>\nKao i svaka SAAS usluga danas, obla\u010dne igre treba da budu dizajnirane da budu horizontalno skalabilne. Konstrukcija \u201ekoordinator-radnik\u201c omogu\u0107ava dodavanje vi\u0161e radnika za pru\u017eanje ve\u0107eg saobra\u0107aja.<\/p>\n<p><b>8. Nema vezanosti za jedan oblak<\/b><br \/>\nInfrastruktura CloudRetro se sme\u0161ta na razli\u010ditim obla\u010dnim provajderima (Digital Ocean, Alibaba, prilago\u0111eni provajder) za razli\u010dite regione. Aktiviram pokretanje u Docker kontejneru za infrastrukturu i pode\u0161avam mre\u017ene parametre pomo\u0107u bash skripte kako bih izbegao zavisnost od jednog obla\u010dnog provajdera. Kombinovanjem ovoga sa NAT Traversal u WebRTC, mo\u017eemo dobiti fleksibilnost za implementaciju CloudRetro na bilo kojoj obla\u010dnoj platformi, pa \u010dak i na ra\u010dunarima bilo kojeg korisnika.<\/p>\n<h3>Arhitektonski dizajn<\/h3>\n<p>\n<b>Radnik:<\/b> (ali streaming server, omenjen zgoraj) pomno\u017ei igre, za\u017eene kodirni tok in prena\u0161a kodirane medije uporabnikom. Worker instance se \u0161irijo po vsem svetu, vsak worker pa lahko hkrati obdeluje ve\u010d uporabni\u0161kih sej.<\/p>\n<p><b>Koordinator:<\/b> je odgovoren za usklajevanje novega uporabnika z najbolj ustreznim workerjem za pretakanje. Koordinator komunicira z workeri prek WebSocket.<\/p>\n<p><b>Shranjevanje igralnih stanj:<\/b> centralno oddaljeno shranjevanje za vsa stanja igre. To shranjevanje zagotavlja pomembne funkcije, kot je oddaljeno shranjevanje\/ nalaganje.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/985447b81350a640b0bd1344b5705113.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nVi\u0161je nivojska arhitektura CloudRetro<\/p>\n<h3>Uporabni\u0161ki scenarij<\/h3>\n<p>\nKo nov uporabnik odpre CloudRetro v korakih 1 in 2, prikazanih na spodnji sliki, se koordinator skupaj s seznamom dostopnih workerjev zahteva na prvi strani. Nato v koraku 3 odjemalec izra\u010duna zakasnitve za vse kandidate z uporabo HTTP ping zahteve. Ta seznam zakasnitev se nato po\u0161lje nazaj koordinatorju, da lahko dolo\u010di najbolj ustreznega workerja za obravnavo uporabnika. V koraku 4 spodaj se ustvari igra. Med uporabnikom in dodeljenim workerjem se vzpostavi tokovno povezavo WebRTC.<br \/>\n<img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/00199b5942e3e4314609ec0e70ea7162.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nUporabni\u0161ki scenarij po pridobitvi dostopa<\/p>\n<h3>Kaj je znotraj workerja<\/h3>\n<p>\nIgralni in pretakajo\u010di tokovi so shranjeni znotraj workerja izolirano in si tam izmenjujejo informacije prek vmesnika. Trenutno se ta povezava izvaja preko prenosa podatkov v pomnilniku po <noindex><a rel=\"nofollow\" href=\"https:\/\/tour.golang.org\/concurrency\/2\">kanalih Golang<\/a><\/noindex> v istem procesu. Naslednji cilj je segregacija, to je neodvisno zagon igre v drugem procesu.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/7a90ec2638344467a34604cd4322165c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nInterakcija komponent workerja<\/p>\n<p>Glavne sestavine:<\/p>\n<ul>\n<li><b>WebRTC:<\/b> odjemalska komponenta, ki sprejema uporabni\u0161ke vnose in posreduje kodirane medije s stre\u017enika.\n<\/li>\n<li><b>Igralni emulator:<\/b> igralna komponenta. Z uporabo knji\u017enice Libretro je sistem sposoben zagnati igro znotraj istega procesa in notranje zajeti medije ter vhodni tok.\n<\/li>\n<li>Utrinki iz igre se zajamejo in po\u0161ljejo v kodirnik.\n<\/li>\n<li><b>Slikovni\/avdio kodirnik:<\/b> kodirni tok, ki sprejema medijske okvirje, jih kodira v ozadju in izhodne kodirane slike\/avdio.\n<\/li>\n<\/ul>\n<p><\/p>\n<h2>Implementacija<\/h2>\n<p>\nCloudRetro se zanima za WebRTC kot klju\u010dno tehnologijo, zato preden se poglobim v podrobnosti implementacije v Golangu, sem se odlo\u010dil, da najprej predstavim samo WebRTC. To je neverjetna tehnologija, ki mi je mo\u010dno pomagala dose\u010di zamudo prenosa podatkov le nekaj del\u010dkov sekunde.<\/p>\n<h3>WebRTC<\/h3>\n<p>\nWebRTC je namenjen zagotavljanju visokokakovostnih peer-to-peer povezav v nativni mobilni aplikaciji in brskalnikih preko preprostih API-jev.<\/p>\n<h4>NAT Traversal <\/h4>\n<p>\nWebRTC je znan po svoji funkcionalnosti NAT Traversal. WebRTC je zasnovan za komunikacijo med enakimi. Njegov cilj je najti najbolj optimalno neposredno pot, ki se izogne NAT prehodom in po\u017earnim zidom za peer-to-peer komunikacijo preko procesa, imenovanega <noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/trickle-ice\/\">ICE<\/a><\/noindex>. V okviru tega procesa API-ji WebRTC najdejo va\u0161 javni IP naslov s pomo\u010djo STUN stre\u017enikov in ga posredujejo na stre\u017enik za ponovni prenos (<noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/?s=turn\">TURN<\/a><\/noindex>), kadar neposredne povezave ni mogo\u010de vzpostaviti.<\/p>\n<p>Vendar CloudRetro te mo\u017enosti ne izkori\u0161\u010da v celoti. Njegove peer-to-peer povezave ne obstajajo med uporabniki, temve\u010d med uporabniki in obla\u010dnimi stre\u017eniki. Stre\u017eni\u0161ki del modela ima manj omejitev za neposredno povezovanje kot obi\u010dajna uporabni\u0161ka naprava. To omogo\u010da predhodno odpiranje vhodnih vrat ali uporabo javnih IP naslovov neposredno, saj stre\u017enik ni za NAT.<\/p>\n<p>V preteklosti sem \u017eelel spremeniti projekt v platformo za distribucijo iger za Cloud Gaming. Ideja je bila, da bi ustvarjalcem iger omogo\u010dili ponujanje iger in preto\u010dnih virov. Uporabniki pa bi neposredno sodelovali s ponudniki. Na tak decentraliziran na\u010din je CloudRetro le okolje za povezovanje zunanjih preto\u010dnih virov z uporabniki, kar omogo\u010da ve\u010djo skalabilnost, ko gostovanje ne obremenjuje ve\u010d njega. Vloga WebRTC NAT Traversal je tukaj zelo pomembna za olaj\u0161anje inicializacije peer-to-peer povezave na zunanjih preto\u010dnih virih, kar poenostavi povezovanje ustvarjalca z omre\u017ejem.<\/p>\n<h4>Stiskanje videa<\/h4>\n<p>\nStiskanje videa je nujen del delovnega procesa, ki znatno prispeva k gladkemu toku. \u010ceprav ni nujno, da poznate vse podrobnosti kodiranja videa v VP8\/H264, razumevanje koncepta pomaga razumeti parametre hitrosti pretakanja videa, odpraviti nepri\u010dakovano vedenje in nastaviti zakasnitev.<\/p>\n<p>Stiskanje videa za pretakanje je zapletena naloga, ker mora algoritem zagotoviti, da je skupni \u010das kodiranja + \u010das prenosa po omre\u017eju + \u010das dekodiranja \u010dim kraj\u0161i. Poleg tega mora biti proces kodiranja dosleden in neprekinjen. Nekatere kompromise pri kodiranju ni mogo\u010de uporabiti \u2013 na primer, ne moremo dati prednosti dalj\u0161emu \u010dasu kodiranja pred manj\u0161im velikostjo datoteke in \u010dasom dekodiranja, ali uporabiti nedosledno stiskanje.<\/p>\n<p>Ideja stiskanja videa je izklju\u010diti odve\u010dne bite informacij, hkrati pa ohraniti sprejemljivo raven natan\u010dnosti za uporabnike. Poleg kodiranja posameznih stati\u010dnih slikovnih okvirjev algoritem izhaja za trenutni okvir iz prej\u0161njega in naslednjega, tako da se po\u0161lje le njihova razlika. Kot je razvidno iz primera s Pacmanom, se prena\u0161ajo le diferencialne to\u010dke.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/e452c54c53ab7797b610620aefbba8d2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nPrimerjava videokadrov na primeru Pacmana<\/p>\n<h4>Stiskanje zvoka<\/h4>\n<p>\nNa podoben na\u010din algoritem za stiskanje zvoka opu\u0161\u010da podatke, ki jih \u010dlovek ne more zaznati. Opus je trenutno avdio kodek z najbolj\u0161o zmogljivostjo. Razvit je za prenos zvo\u010dnih valov preko protokola urejenih podatkovnih gramov, kot je RTP (Real-time Transport Protocol \u2013 protokol za prenos v realnem \u010dasu). Njegova zamuda je manj\u0161a kot pri mp3 in aac, kakovost pa vi\u0161ja. Zamuda obi\u010dajno zna\u0161a okoli 5~66,5 ms.<\/p>\n<h4>Pion, WebRTC v Golangu<\/h4>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pion\/webrtc\">Pion<\/a><\/noindex> je projekt z odprto kodo, ki prena\u0161a WebRTC na Golang. Namesto obi\u010dajnega ovijanja doma\u010dih C++ knji\u017enic WebRTC je Pion izvorna implementacija WebRTC v Golangu z bolj\u0161o zmogljivostjo, integracijo z Go in nadzorom razli\u010dic na protokolih WebRTC.<\/p>\n<p>Knji\u017enica prav tako omogo\u010da pretakanje podatkov z veliko odli\u010dnimi vgrajenimi moduli, z zamudo manj kot sekundo. Ima svojo lastno implementacijo STUN, DTLS, SCTP itd., pa tudi nekaj eksperimentov s QUIC in WebAssembly. Sama po sebi je ta odprtokodna knji\u017enica resni\u010dno dober vir za u\u010denje z odli\u010dno dokumentacijo, implementacijo omre\u017enih protokolov in odli\u010dnimi primeri.<\/p>\n<p>Skupnost Pion, ki jo vodi zelo strasten ustvarjalec, je precej \u017eivahna, poteka veliko kakovostnih razprav o WebRTC. \u010ce vas ta tehnologija zanima, se pridru\u017eite <noindex><a rel=\"nofollow\" href=\"http:\/\/pion.ly\/slack\">http:\/\/pion.ly\/slack<\/a><\/noindex> \u2013 spoznali boste veliko novega.<\/p>\n<h3>Pisanje CloudRetro v Golangu<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/f85f7b8ea579fab964d870aad698c7e7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nImplementacija delavca v Go<\/p>\n<h4>Kanali Go v akciji<\/h4>\n<p>\nZaradi lepe zasnove kanalov Go so te\u017eave s pretakanjem dogodkov in paralelizmom bistveno poenostavljene. Tako kot v diagramu v razli\u010dnih GoRoutines so vzporedno aktivni razli\u010dni sestavni deli. Vsaka komponenta upravlja svoje stanje in komunicira prek kanalov. Izbira Golanga zahteva, da se obravnava eno atomsko dejanje vsak trenutek v igri (game tick). To pomeni, da za tak\u0161no zasnovo ni potrebna zaklenitev. Na primer, ko se uporabnik shrani, je potreben popoln posnetek stanja igre. To stanje mora ostati neprekinjeno, medtem ko se izvaja vnos, dokler ni shranjevanje zaklju\u010deno. Med vsakim game tickom lahko zadnja stran obravnava le operacijo shranjevanja ali vnosa, kar pomeni, da je postopek varno za multi-threading.<\/p>\n<pre><code class=\"go\">func (e *gameEmulator) gameUpdate() {\nfor {\n\tselect {\n\t\tcase &lt;-e.saveOperation:\n\t\t\te.saveGameState()\n\t\tcase key := &lt;-e.input:\n\t\t\te.updateGameState(key)\n\t\tcase &lt;-e.done:\n\t\t\te.close()\n\t\t\treturn\n\t}\n    }\n}<\/code><\/pre>\n<p><\/p>\n<h4>Fan-in \/ Fan-out<\/h4>\n<p>\nTa vzorec Golang je odli\u010den za mojo uporabo pri CrowdPlay in ve\u010d igralcih. V skladu s tem vzorcem se vsi uporabni\u0161ki vnosi v eni sobi vklju\u010dijo v osrednji vhodni kanal. Gaming media se nato razdelijo na vse uporabnike v eni sobi. Tako dose\u017eemo delitev stanja igre med ve\u010d igralnimi sejami razli\u010dnih uporabnikov.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje z odprtim izvorom na WebRTC: p2p, multiplayer, brez zakasnitev.\" src=\"\/wp-content\/uploads\/2020\/07\/000a495d7f214246a8a396aab11a3ac5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSinhronizacija med razli\u010dnimi sejami<\/p>\n<h4>Slabosti Golanga<\/h4>\n<p>\nGolang nije savr\u0161en. Kanal je spor. U pore\u0111enju sa blokadama, Go kanal je jednostavniji na\u010din obrade paralelnih i tokovnih doga\u0111aja, ali kanal ne pru\u017ea najbolju performansu. Pod kanalom postoji slo\u017eena logika blokiranja. Zato sam napravio neke izmene u implementaciji, ponovo koriste\u0107i blokade i atomske vrednosti prilikom zamene kanala radi optimizacije performansi.<\/p>\n<p>Pored toga, garbage collector u Golangu nije upravljan, zbog \u010dega ponekad dolazi do sumnjivo dugih pauza. Ovo znatno ometa rad aplikacije u realnom vremenu.<\/p>\n<h4>CGO<\/h4>\n<p>\nU projektu se koristi postoje\u0107a VP8\/H264 biblioteka Golang sa otvorenim izvorom za kompresiju medija i Libretro za emulatore igara. Sve ove biblioteke su jednostavne omotnice C biblioteke u Go koriste\u0107i <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/cmd\/cgo\/\">CGO<\/a><\/noindex>. Neki od nedostataka su navedeni u <noindex><a rel=\"nofollow\" href=\"https:\/\/dave.cheney.net\/2019\/10\/06\/use-internal-packages-to-reduce-your-public-api-surface\">ovom postu Davea Cheneya<\/a><\/noindex>. Problemi sa kojima sam se suo\u010dio:<\/p>\n<ul>\n<li>nemogu\u0107nost hvatanja pada u CGO, \u010dak i uz pomo\u0107 Golang RecoveryCrash;<\/li>\n<li>nemogu\u0107nost odre\u0111ivanja uskog grla u performansama kada ne mo\u017eemo otkriti detaljne probleme u CGO.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Zaklju\u010dek<\/h2>\n<p>\nPostigao sam svoj cilj \u2013 razumeo sam usluge cloud gaming-a i razvio platformu koja poma\u017ee igranje nostalgi\u010dnih retro igara s mojim prijateljima online. Stvaranje ovog projekta ne bi bilo mogu\u0107e bez Pion biblioteke i podr\u0161ke Pion zajednice. Izuzetno sam zahvalan na njegovom intenzivnom razvoju. Jednostavni API-ji koje pru\u017eaju WebRTC i Pion omogu\u0107ili su glatku integraciju. Moja prva konceptualna dokazna verzija je objavljena u istom nedelji, iako prethodno nisam znao o peer-to-peer vezi (P2P).<\/p>\n<p>Uprkos jednostavnosti integracije, P2P strimovanje je zaista veoma slo\u017eena oblast u ra\u010dunarstvu. Bavi se slo\u017eeno\u0161\u0107u vi\u0161egodi\u0161njih mre\u017enih arhitektura, kao \u0161to su IP i NAT, za stvaranje peer-to-peer sesije. Tokom rada na ovom projektu, stekao sam mnogo dragocenih znanja o mre\u017eama i optimizaciji performansi, pa preporu\u010dujem svima da poku\u0161aju izgraditi P2P proizvode uz pomo\u0107 WebRTC.<\/p>\n<p>CloudRetro pokriva sve upotrebe koje sam o\u010dekivao kao retro gejmer. Ipak, mislim da postoji mnogo oblasti u projektu koje mogu pobolj\u0161ati, kao \u0161to su u\u010diniti mre\u017eu pouzdanijom i efikasnijom, obezbediti bolji kvalitet grafike igara ili omogu\u0107iti deljenje igara me\u0111u korisnicima. Naporno radim na tome. Molim vas, pratite <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">projekat<\/a><\/noindex> i podr\u017eite ga ako vam se svi\u0111a.<\/li>\n<\/ul>\n<p>Izvor: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/Voximplant\/blog\/511626\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u041e \u043a\u0430\u043a \u0443\u0441\u043b\u0443\u0433\u0430, \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u0430\u043a \u0443\u0441\u043b\u0443\u0433\u0430, \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u043a\u0430\u043a \u0443\u0441\u043b\u0443\u0433\u0430, \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u043a\u0430\u043a \u0443\u0441\u043b\u0443\u0433\u0430, \u0432\u0438\u0434\u0435\u043e\u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 \u043a\u0430\u043a \u0443\u0441\u043b\u0443\u0433\u0430, \u0430 \u0447\u0442\u043e \u043d\u0430\u0441\u0447\u0435\u0442 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0438\u0433\u0440 \u043a\u0430\u043a \u0443\u0441\u043b\u0443\u0433\u0438? \u0423\u0436\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u0438\u0433\u0440 (Cloud Gaming), \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Stadia, \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u0430\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0435\u0439 Google. Stadia \u043d\u0435 \u043d\u043e\u0432\u0438\u0447\u043e\u043a \u0432 WebRTC, \u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c WebRTC \u0442\u0430\u043a \u0436\u0435? \u0422\u0445\u0430\u043d\u044c \u041d\u0433\u0443\u0435\u043d (Thanh [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":89304,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-89303","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sl_SI\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 \u0433\u0435\u0439\u043c\u0438\u043d\u0433 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u043d\u0430 WebRTC: p2p, \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0435\u0435\u0440, zero latency | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-07-21T23:42:30+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-21T23:42:30+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Cloud gaming s otvorenim izvorom na WebRTC: p2p, multiplayer, nulta latencija | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sl_SI","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 \u0433\u0435\u0439\u043c\u0438\u043d\u0433 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u043d\u0430 WebRTC: p2p, \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0435\u0435\u0440, zero latency | ProHoster","og:url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-21T23:42:30+00:00","article:modified_time":"2020-07-21T23:42:30+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"89303","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:12:27","updated":"2022-09-29 13:03:06","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/89303","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/comments?post=89303"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/89303\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media\/89304"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media?parent=89303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/categories?post=89303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/tags?post=89303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}