{"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\/hr\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency","title":{"rendered":"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency","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 s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/22dbf7665d7fded15671d98a2afe599b.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\nUsluga kao platforma, infrastruktura kao usluga, platforma kao usluga, komunikacijska platforma kao usluga, videokonferencije kao usluga, a \u0161to ka\u017eete na obla\u010dne igre kao uslugu? Ve\u0107 je bilo nekoliko poku\u0161aja stvaranja obla\u010dnih igara (Cloud Gaming), poput Stadije, nedavno pokrenute od strane Googlea. Stadia <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/avtlQeaxd_I?t=440\">nije novost u WebRTC-u<\/a><\/noindex>, ali mogu li i drugi koristiti WebRTC na sli\u010dan na\u010din?<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Than Nguyen odlu\u010dio je provjeriti ovu mogu\u0107nost na svom open-source projektu CloudRetro. CloudRetro se temelji na Pionu, <noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/webrtc-open-source-most-popular\/\">popularnoj<\/a><\/noindex> WebRTC biblioteci temeljnoj na Golu (hvala <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Sean-Der\">Shonu<\/a><\/noindex> iz Pionovog razvojnog tima na pomo\u0107i u pripremi ovog \u010dlanka). U ovom \u010dlanku, Than daje pregled arhitekture svog projekta te dijeli korisne informacije i izazove na koje je nai\u0161ao tijekom rada.<\/p>\n<h2>Uvod<\/h2>\n<p>\nPro\u0161le godine, kada je Google najavio Stadiju, jednostavno sam bio odu\u0161evljen. Ideja je toliko jedinstvena i inovativna da sam se neprekidno pitao kako je to uop\u0107e mogu\u0107e sa postoje\u0107im tehnologijama. \u017delja da bolje razumijem ovu temu potaknula me je da izradim svoju verziju open-source obla\u010dne igre. Rezultat je bio fantasti\u010dan. U nastavku bih volio podijeliti proces rada na mom godi\u0161njem <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">projektu<\/a><\/noindex>.<\/p>\n<p><i>TLDR: kratka verzija s najva\u017enijim to\u010dkama<\/i><\/p>\n<h3>Za\u0161to su obla\u010dne igre budu\u0107nost<\/h3>\n<p>\nVjerujem da \u0107e Cloud Gaming uskoro postati nova generacija ne samo igara, ve\u0107 i drugih podru\u010dja informatike. Obla\u010dne igre predstavljaju vrhunac modela klijent\/server. Ovaj model maksimizira upravljanje backendom i minimizira rad frontenda premje\u0161tanjem logike igre na udaljeni poslu\u017eitelj i strujanjem slika\/audija klijentu. Poslu\u017eitelj provodi te\u0161ku obradu, stoga klijent vi\u0161e ne ovisi o hardverskim ograni\u010denjima.<\/p>\n<p>Google Stadia, u su\u0161tini, omogu\u0107uje igranje u <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-igrama<\/a><\/noindex> (tj. visokoinvesticijskim blockbuster igrama) putem su\u010delja sli\u010dnog YouTube-u. Ista metodologija mo\u017ee se primijeniti i na druge te\u0161ke offline aplikacije, poput operativnog sustava ili 2D\/3D grafi\u010dkog dizajna itd., kako bismo ih stabilno pokretali na ure\u0111ajima s niskim tehni\u010dkim karakteristikama na razli\u010ditim platformama.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/d6ca3e47db5c8e3d9880b304cc3be33b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nBudu\u0107nost ove tehnologije: zamislite da Microsoft Windows 10 radi u pregledniku Chrome?<\/p>\n<h3>Obla\u010dne igre su tehni\u010dki slo\u017eene<\/h3>\n<p>\nIgranje je jedno od rijetkih podru\u010dja gdje je potrebna izuzetno brza reakcija korisnika. Ako se ponekad suo\u010dimo s odgodom od 2 sekunde prilikom klika na stranicu, to je prihvatljivo. Video streamovi u stvarnom vremenu obi\u010dno kasne nekoliko sekundi, ali i dalje pru\u017eaju dovoljno udobnosti za kori\u0161tenje. Me\u0111utim, ako igra \u010desto ima ka\u0161njenje od 500 ms, jednostavno je nemogu\u0107e igrati. Na\u0161 cilj je posti\u0107i izuzetno nisku latenciju, kako bi razlika izme\u0111u unosa i medija bila \u0161to manja. Stoga, tradicionalni pristup streamingu videa ovdje nije primjenjiv.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/d73765a3c9277c026f407883e1091473.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nOp\u0107i model cloud gaming-a<\/p>\n<h2>Open source projekt CloudRetro<\/h2>\n<p>\nOdlu\u010dio sam stvoriti testni uzorak cloud gaming-a kako bih provjerio je li to sve mogu\u0107e pri tako strogim mre\u017enim ograni\u010denjima. Za provjeru koncepta odabrao sam Golang, jer je to jezik s kojim sam najvi\u0161e upoznat i koji se pokazao kao vrlo prikladan za ovu implementaciju iz mnogih drugih razloga, kako se kasnije ispostavilo. Go je jednostavan i brzo se razvija; kanali u Go-u savr\u0161eno su prikladni za upravljanje vi\u0161edretveno\u0161\u0107u.<\/p>\n<p>Projekt <noindex><a rel=\"nofollow\" href=\"http:\/\/cloudretro.io\/\">CloudRetro.io<\/a><\/noindex> \u2013 cloud gaming usluga s otvorenim kodom za retro igre. Cilj projekta je u klasi\u010dne retro igre uvesti najugodnije igra\u010dke do\u017eivljaje i dodati multiplayer.<br \/>\nDetaljnije upoznavanje s projektom mo\u017eete prona\u0107i ovdje: <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>\nZa demonstraciju cijele snage cloud gaming-a, CloudRetro koristi retro igre. To omogu\u0107ava stjecanje mno\u0161tva jedinstvenih igra\u010dkih iskustava.<\/p>\n<ul>\n<li>Portabilnost igre\n<ul>\n<li>Trenutno reprodukcija prilikom otvaranja stranice; preuzimanje i instalacija nisu potrebni.<\/li>\n<li>Radi u mobilnom pregledniku, tako da nije potrebno nikakvo softversko rje\u0161enje za pokretanje.<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>Igra\u010dke sesije mogu se dijeliti na vi\u0161e ure\u0111aja i pohranjivati u oblaku za sljede\u0107i ulaz.<\/li>\n<li>Igru je mogu\u0107e streamati, a mo\u017ee se igrati i odjednom s vi\u0161e korisnika:\n<ul>\n<li>Crowdplay tipa TwitchPlayPokemon, samo vi\u0161e cross-platform i vi\u0161e u stvarnom vremenu.<\/li>\n<li>Offline igre u online modu. Mnogi korisnici mogu igrati bez postavljanja 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 s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/bdc715971755d669a026f830ce888520.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDemo verzija vi\u0161ekorisni\u010dke online igre na razli\u010ditim ure\u0111ajima.<\/p>\n<h2>Infrastruktura<\/h2>\n<p><\/p>\n<h3>Zahtjevi i tehnologije<\/h3>\n<p>\nU nastavku je popis zahtjeva koje sam postavio prije po\u010detka projekta.<\/p>\n<p><b>1. Jedan igra\u010d<\/b><br \/>\nOvaj zahtjev se mo\u017ee \u010diniti manje va\u017enim i o\u010ditim, ali to je jedan od mojih klju\u010dnih zaklju\u010daka, omogu\u0107ava oblak igrama da se dr\u017ee \u0161to dalje od tradicionalnih streaming usluga. Ako se fokusiramo na igra\u010da s jednim igra\u010dem, mo\u017eemo se osloboditi centraliziranih servera ili CDN-a, jer ne trebamo prenositi sadr\u017eaj masama. Umjesto da u\u010ditavamo streamove na prenapu\u010deni server ili \u0161aljemo pakete na centralizirani WebSocket server, usluge streama se izravno prenosu korisniku putem peer-to-peer WebRTC veze.<\/p>\n<p><b>2. Medijski tok s niskom latencijom<\/b><br \/>\n\u010citaju\u0107i o Stadiji, \u010desto susre\u0107em spominjanje WebRTC-a u nekim \u010dlancima. Shvatio sam da je WebRTC izvanredna tehnologija i da savr\u0161eno odgovara za kori\u0161tenje u obla\u010dnim igrama. WebRTC je projekt koji web preglednicima i mobilnim aplikacijama omogu\u0107uje komunikaciju u stvarnom vremenu kroz jednostavan API. Osigurava peer-to-peer vezu optimiziranu za medije i ima ugra\u0111ene standardne kodeke kao \u0161to su VP8 i H264.<\/p>\n<p>Davao sam prioritet osiguravanju maksimalne udobnosti za korisnike, a ne o\u010duvanju visokog kvaliteta grafike. U algoritmu su dopu\u0161teni odre\u0111eni gubici. U Google Stadiji postoji dodatni korak za smanjenje veli\u010dine slike na serveru, a okviri se skaliraju na vi\u0161u kvalitetu prije nego \u0161to se prenesu peer-to-peer \u010dvorovima.<\/p>\n<p><b>3. Distribuirana infrastruktura s geografskom usmjeravanjem<\/b><br \/>\nBez obzira na to koliko je algoritam kompresije optimiziran i kod, mre\u017ea ostaje odlu\u010duju\u0107i faktor koji najvi\u0161e pridonosi latenciji. Arhitektura mora imati mehanizam za povezivanje najbli\u017eeg servera korisniku kako bi se smanjilo vrijeme prijenosa (RTT). Arhitektura bi trebala imati 1 koordinatora i vi\u0161e streaming servera raspore\u0111enih \u0161irom svijeta: Zapad SAD-a, Istok SAD-a, Europa, Singapur, Kina. Svi streaming serveri moraju biti potpuno izolirani. Sustav mo\u017ee regulirati svoje raspodjele kada server pristupi mre\u017ei ili se povu\u010de. Tako\u0111er, tijekom velikog prometa, dodavanje dodatnih servera omogu\u0107uje horizontalno skaliranje.<\/p>\n<p><b>4. Kompatibilnost preglednika<\/b><br \/>\nCloud gaming shines when it requires minimal effort from users. This means that it can be launched in a browser. Browsers help make the gaming experience as comfortable as possible for users by eliminating the need to install software and hardware. Browsers also help ensure cross-platform compatibility for both mobile and desktop versions. Fortunately, WebRTC is well supported across different browsers.<\/p>\n<p><b>5. Clear separation of the gaming interface and service<\/b><br \/>\nI view the cloud gaming service as a platform. Everyone should have the ability to connect anything to the platform. Currently, I have integrated <noindex><a rel=\"nofollow\" href=\"http:\/\/LibRetro\">LibRetro<\/a><\/noindex> with the cloud gaming service because LibRetro offers a beautiful emulator interface for retro games such as SNES, GBA, and PS.<\/p>\n<p><b>6. Rooms for multiplayer, crowd play, and deep linking to games<\/b><br \/>\nCloudRetro supports many new gameplay modes, such as CrowdPlay and Online MultiPlayer for retro games. If multiple users open the same deep link on different computers, they will see the same running game and even be able to join it.<\/p>\n<p>Moreover, game states are stored in cloud storage. This allows users to continue playing at any time on any other device.<\/p>\n<p><b>7. Horizontal scaling<\/b><br \/>\nLike any SAAS today, cloud gaming must be designed to be horizontally scalable. The coordinator-worker architecture allows for adding more workers to handle greater traffic.<\/p>\n<p><b>8. No dependency on a single cloud<\/b><br \/>\nThe CloudRetro infrastructure is hosted on various cloud providers (Digital Ocean, Alibaba, custom provider) for different regions. I activate launching in a Docker container for the infrastructure and configure the network settings using a bash script to avoid reliance on a single cloud provider. By combining this with NAT Traversal in WebRTC, we can gain flexibility to deploy CloudRetro on any cloud platform and even on users' machines.<\/p>\n<h3>Architectural design<\/h3>\n<p>\n<b>Worker:<\/b> (ili striming poslu\u017eitelj, spomenut ranije) multiplicira igre, pokre\u0107e kodiraju\u0107i pipeline i prenosi kodirani medij korisnicima. Instance radnika su raspore\u0111ene \u0161irom svijeta, a svaki radnik mo\u017ee obraditi nekoliko korisni\u010dkih sesija istovremeno.<\/p>\n<p><b>Koordinator:<\/b> odgovara za spajanje novog korisnika s najprikladnijim radnikom za striming. Koordinator komunicira s radnicima putem WebSocket-a.<\/p>\n<p><b>Skladi\u0161te stanja igara:<\/b> centralno udaljeno skladi\u0161te za sve statuse igre. Ovo skladi\u0161te omogu\u0107ava va\u017ene funkcije kao \u0161to su udaljeno spremanje\/u\u010ditavanje.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/985447b81350a640b0bd1344b5705113.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nArhitektura CloudRetro na visokom nivou<\/p>\n<h3>Korisni\u010dki scenarij<\/h3>\n<p>\nKada novi korisnik otvori CloudRetro na koracima 1 i 2, prikazanim na slici ispod, koordinator zajedno s popisom dostupnih radnika tra\u017ei prvu stranicu. Nakon toga, u koraku 3, klijent izra\u010dunava latencije za sve kandidate putem HTTP zahtjeva ping. Ovaj popis latencija se zatim \u0161alje natrag koordinatoru kako bi mogao odrediti najprikladnijeg radnika za uslu\u017eivanje korisnika. U koraku 4 ispod se stvara igra. Izme\u0111u korisnika i dodijeljenog radnika uspostavlja se streaming veza WebRTC.<br \/>\n<img decoding=\"async\" alt=\"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/00199b5942e3e4314609ec0e70ea7162.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nKorisni\u010dki scenarij nakon pristupa<\/p>\n<h3>\u0160to se nalazi unutar radnika<\/h3>\n<p>\nIgra\u010dki i striming pipelini su pohranjeni unutar radnika izolirano i razmjenjuju informacije putem su\u010delja. Trenutno se ova veza ostvaruje putem prijenosa podataka u memoriji preko <noindex><a rel=\"nofollow\" href=\"https:\/\/tour.golang.org\/concurrency\/2\">kanala Golang<\/a><\/noindex> u istom procesu. Sljede\u0107i cilj je segregacija, tj. neovisno pokretanje igre u drugom procesu.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/7a90ec2638344467a34604cd4322165c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nInterakcija komponenata radnika<\/p>\n<p>Glavne komponente:<\/p>\n<ul>\n<li><b>WebRTC:<\/b> klijentska komponenta koja prihva\u0107a korisni\u010dki unos i isporu\u010duje kodirani medij s poslu\u017eitelja.\n<\/li>\n<li><b>Igra\u010dki emulator:<\/b> igra\u010dka komponenta. Zahvaljuju\u0107i biblioteci Libretro, sustav je sposoban pokrenuti igru unutar istog procesa i interno presretati medije i tok unosa.\n<\/li>\n<li>Unutarnji okviri igre se snimaju i \u0161alju u kodira\u010d.\n<\/li>\n<li><b>Slika\/audio kodira\u010d:<\/b> kodiraju\u0107i pipeline koji prihva\u0107a medijske okvire, kodira ih u pozadini i isporu\u010duje kodirane slike\/audio.\n<\/li>\n<\/ul>\n<p><\/p>\n<h2>Implementacija<\/h2>\n<p>\nCloudRetro se oslanja na WebRTC kao klju\u010dnu tehnologiju, stoga sam, prije nego \u0161to se duboko posvetim detaljima implementacije u Golangu, odlu\u010dio govoriti o samom WebRTC-u. Ovo je nevjerojatna tehnologija koja mi je jako pomogla u postizanju ka\u0161njenja prijenosa podataka od samo dijela sekunde.<\/p>\n<h3>WebRTC<\/h3>\n<p>\nWebRTC je namijenjen osiguravanju visokokvalitetnih peer-to-peer povezivanja na nativnim mobilnim aplikacijama i u preglednicima pomo\u0107u jednostavnih API-ja.<\/p>\n<h4>NAT Traversal <\/h4>\n<p>\nWebRTC je poznat po svojoj funkcionalnosti NAT Traversal. WebRTC je namijenjen peer-to-peer komunikaciji. Njegov cilj je prona\u0107i najprikladniji izravni put, izbjegavaju\u0107i NAT usmjeriva\u010de i vatrozidove za peer-to-peer komunikaciju putem procesa nazvanog <noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/trickle-ice\/\">ICE<\/a><\/noindex>. U okviru ovog procesa API WebRTC pronalazi va\u0161u javnu IP adresu pomo\u0107u STUN poslu\u017eitelja i proslje\u0111uje je na poslu\u017eitelj za preusmjeravanje (<noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/?s=turn\">TURN<\/a><\/noindex>), kada izravna veza ne mo\u017ee biti uspostavljena.<\/p>\n<p>Me\u0111utim, CloudRetro ne koristi potpuno ovu mogu\u0107nost. Njegove peer-to-peer veze ne postoje izme\u0111u korisnika, ve\u0107 izme\u0111u korisnika i cloud poslu\u017eitelja. Serverska strana modela ima manje ograni\u010denja na izravnu komunikaciju od obi\u010dnog korisni\u010dkog ure\u0111aja. Ovo omogu\u0107ava prethodno otvaranje dolaznih portova ili izravnu upotrebu javnih IP adresa, budu\u0107i da poslu\u017eitelj nije iza NAT-a.<\/p>\n<p>Nekada sam \u017eelio pretvoriti projekt u platformu za distribuciju igara za Cloud Gaming. Ideja je bila omogu\u0107iti kreatorima igara da pru\u017eaju igre i resurse za streaming, dok bi korisnici izravno komunicirali s pru\u017eateljima. Na takav decentralizirani na\u010din, CloudRetro je samo okru\u017eenje za povezivanje vanjskih resursa streaminga s korisnicima, \u010dime postaje skalabilniji jer vi\u0161e ne ovisi o hostingu. Uloga WebRTC NAT Traversala ovdje je vrlo va\u017ena za olak\u0161avanje inicijalizacije peer-to-peer veze na vanjskim resursima streaminga, \u0161to pojednostavljuje povezivanje kreatora s mre\u017eom.<\/p>\n<h4>Kompresija videa<\/h4>\n<p>\nKompresija videa je neizostavan deo radnog toka koji u velikoj meri doprinosi fluidnosti strimovanja. Iako nije neophodno znati sve detalje kodiranja videa u VP8\/H264, razumevanje koncepcije poma\u017ee u razumevanju parametara brzine strimovanja, re\u0161avanju neo\u010dekivanog pona\u0161anja i pode\u0161avanju latencije.<\/p>\n<p>Kompresija videa za streaming servis predstavlja slo\u017een zadatak, jer algoritam mora osigurati da je ukupno vreme kodiranja + vreme prenosa preko mre\u017ee + vreme dekodiranja \u0161to je mogu\u0107e manje. Pored toga, proces kodiranja mora biti dosledan i neprestan. Neki me\u0111usobni ustupci tokom kodiranja nisu primenjivi \u2013 na primer, ne mo\u017eemo dati prednost du\u017eem vremenu kodiranja ispred manjeg veli\u010dine datoteke i vremena dekodiranja, niti koristiti nedoslednu kompresiju.<\/p>\n<p>Ideja kompresije videa je da isklju\u010di nepotrebne bitove informacija, dok zadr\u017eava prihvatljiv nivo ta\u010dnosti za korisnike. Osim kodiranja pojedina\u010dnih stati\u010dnih okvira slike, algoritam izvodi trenutno okvir iz prethodnog i slede\u0107eg, tako da se \u0161alje samo njihova razlika. Kao \u0161to se mo\u017ee videti u primeru sa Pacman-om, \u0161alju se samo diferencijalne ta\u010dke.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/e452c54c53ab7797b610620aefbba8d2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nPore\u0111enje video okvira na primeru Pacman<\/p>\n<h4>Kompresija zvuka<\/h4>\n<p>\nNa sli\u010dan na\u010din, algoritam za kompresiju zvuka izostavlja podatke koji ne mogu biti percipirani od strane \u010doveka. Opus je trenutno audio kodek sa najboljom performansom. On je dizajniran za prenos audio talasa preko protokola ure\u0111enih datagrama, kao \u0161to je RTP (Real Time Transport Protocol \u2013 protokol za prenos podataka u realnom vremenu). Njegova latencija je manja od mp3 i aac, a kvalitet je vi\u0161i. Latencija obi\u010dno iznosi oko 5~66,5 ms.<\/p>\n<h4>Pion, WebRTC u Golangu<\/h4>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pion\/webrtc\">Pion<\/a><\/noindex> je projekat otvorenog koda koji donosi WebRTC u Golang. Umesto uobi\u010dajenog omotavanja nativnih C++ biblioteka WebRTC, Pion je nativna Golang implementacija WebRTC sa boljim performansama, integracijom sa Go, kao i kontrolom verzija na protokolima WebRTC.<\/p>\n<p>Biblioteka tako\u0111er omogu\u0107uje streamanje podataka s brojnim odli\u010dnim ugra\u0111enim modulima s latencijom manjom od sekunde. Ima svoju vlastitu implementaciju STUN, DTLS, SCTP i tako dalje, kao i neka eksperimentalna rje\u0161enja s QUIC-om i WebAssembly-om. Sama po sebi, ova open-source biblioteka je zaista dobar izvor za u\u010denje s odli\u010dnom dokumentacijom, implementacijom mre\u017enih protokola i odli\u010dnim primjerima.<\/p>\n<p>Pion zajednica, vo\u0111ena veoma strastvenim tvorcem, prili\u010dno je aktivna i vodi se mnogo kvalitetnih rasprava o WebRTC-u. Ako vas zanima ova tehnologija, pridru\u017eite se <noindex><a rel=\"nofollow\" href=\"http:\/\/pion.ly\/slack\">http:\/\/pion.ly\/slack<\/a><\/noindex> \u2013 saznat \u0107ete mnogo novog.<\/p>\n<h3>Pisanje CloudRetro-a na Golangu<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/f85f7b8ea579fab964d870aad698c7e7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nImplementacija radnika u Go-u<\/p>\n<h4>Go kanali u akciji<\/h4>\n<p>\nZbog lijepog dizajna Go kanala, problemi streamanja doga\u0111aja i paralelizma se zna\u010dajno pojednostavljuju. Kao \u0161to je prikazano na dijagramu, u razli\u010ditim GoRutinama istovremeno radi nekoliko komponenti. Svaka komponenta upravlja svojim stanjem i komunicira preko kanala. Izborna izjava Golanga osigurava da se obra\u0111uje samo jedno atomarno stanje u svakom trenutku u igri (game tick). To zna\u010di da za takav dizajn nije potrebna blokada. Na primjer, kada se korisnik sprema, potreban je puni snapshot stanja igre. Ovo stanje mora ostati neprekidno, obavljaju\u0107i ulaz sve dok spremanje nije zavr\u0161eno. Tijekom svakog game tick-a, backend mo\u017ee obra\u0111ivati samo operaciju spremanja ili ulaza, \u0161to proces \u010dini sigurnim za rad u vi\u0161ekorisni\u010dkom okru\u017eenju.<\/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>\nOva Golang \u0161ablona je savr\u0161ena za moj scenarij kori\u0161tenja CrowdPlay-a i Multiple Player-a. Slijede\u0107i ovu \u0161ablonu, svi korisni\u010dki unosi u jednoj sobi se integriraju u centralni ulazni kanal. Igra\u010dka sredstva se tada distribuiraju svim korisnicima u toj sobi. Na taj na\u010din posti\u017eemo dijeljenje stanja igre izme\u0111u nekoliko igra\u0107ih sesija razli\u010ditih korisnika.<\/p>\n<p><img decoding=\"async\" alt=\"Obla\u010dno igranje s otvorenim izvorom na WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/000a495d7f214246a8a396aab11a3ac5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSinkronizacija izme\u0111u razli\u010ditih sesija<\/p>\n<h4>Nedostaci Golanga<\/h4>\n<p>\nGolang nije savr\u0161en. Kanal je spor. U usporedbi sa blokiranjem, kanal Go je jednostavniji na\u010din obrade paralelnih i strimskih doga\u0111aja, no kanal ne pru\u017ea najbolju izvedbu. ispod kanala postoji slo\u017eena logika blokiranja. Stoga sam uveo neke izmjene u implementaciju ponovnim kori\u0161tenjem blokada i atomski vrijednosti umjesto kanala za optimizaciju performansi.<\/p>\n<p>Osim toga, garbage collector u Golangu je neure\u0111en, \u0161to ponekad dovodi do sumnjivih dugih pauza. To zna\u010dajno ometa rad strim aplikacije u stvarnom vremenu.<\/p>\n<h4>CGO<\/h4>\n<p>\nU projektu se koristi postoje\u0107a VP8\/H264 Golang biblioteka otvorenog koda za kompresiju medija i Libretro za igre emulatora. Sve te biblioteke su zapravo omote C biblioteke u Go koriste\u0107i <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/cmd\/cgo\/\">CGO<\/a><\/noindex>. Neki od nedostataka navedeni su u <noindex><a rel=\"nofollow\" href=\"https:\/\/dave.cheney.net\/2019\/10\/06\/use-internal-packages-to-reduce-your-public-api-surface\">ovoj objavi Davea Cheneyja<\/a><\/noindex>. Problemi s kojima sam se suo\u010dio su:<\/p>\n<ul>\n<li>nemogu\u0107nost hvatanja padova u CGO-u, \u010dak i uz pomo\u0107 Golang RecoveryCrash;<\/li>\n<li>nemogu\u0107nost identifikacije uskog grla u performansama kada ne mo\u017eemo otkriti detaljne probleme u CGO-u.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Zaklju\u010dak<\/h2>\n<p>\nPostigao sam svoj cilj \u2013 razumio sam usluge oblaka igara i stvorio platformu koja poma\u017ee igrati nostalgi\u010dne retro igre s mojim prijateljima online. Izrada ovog projekta ne bi bila mogu\u0107a bez Pion biblioteke i podr\u0161ke zajednice Pion. Izuzetno sam zahvalan na njegovoj intenzivnoj podr\u0161ci. Jednostavna API-ja koje pru\u017eaju WebRTC i Pion omogu\u0107ila su glatku integraciju. Moj prvi dokaz koncepta objavljen je u istom tjednu, iako nisam unaprijed znao o peer-to-peer vezi (P2P).<\/p>\n<p>Iako je integracija jednostavna, P2P strimovanje je zapravo vrlo slo\u017eno podru\u010dje ra\u010dunalnih znanosti. Mora se nositi sa slo\u017eeno\u0161\u0107u dugogodi\u0161njih mre\u017enih arhitektura poput IP-a i NAT-a za uspostavljanje peer-to-peer sesije. Tijekom rada na ovom projektu stekao sam mnogo vrijednih znanja o mre\u017ei i optimizaciji performansi, pa preporu\u010dujem svima da poku\u0161aju izgraditi P2P proizvode pomo\u0107u WebRTC-a.<\/p>\n<p>CloudRetro podr\u017eava sve scenarije kori\u0161tenja koje sam o\u010dekivao s mog stajali\u0161ta kao retro igra\u010da. Me\u0111utim, mislim da postoji mnogo podru\u010dja u projektu koja mogu pobolj\u0161ati, poput pove\u0107anja pouzdanosti i performansi mre\u017ee, osiguravanja boljeg kvaliteta grafike igara ili mogu\u0107nosti dijeljenja igara me\u0111u korisnicima. Naporno radim na tome. Molim vas, pratite <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">projektu<\/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\/hr\/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=\"hr_HR\" \/>\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\/hr\/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\udd47Obla\u010dno igranje s otvorenim kodom na WebRTC: p2p, multiplayer, nulta latencija | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/hr\/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":"hr_HR","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\/hr\/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\/hr\/wp-json\/wp\/v2\/posts\/89303","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=89303"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/89303\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media\/89304"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=89303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=89303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=89303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}