{"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\/ro\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency","title":{"rendered":"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103","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=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/22dbf7665d7fded15671d98a2afe599b.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\nSoftware as a Service, Infrastructure as a Service, Platform as a Service, Communication Platform as a Service, Video Conferencing as a Service, but what about Cloud Gaming as a Service? Several attempts have already been made to create Cloud Gaming, such as Stadia, recently launched by Google. <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/avtlQeaxd_I?t=440\">is no stranger to WebRTC<\/a><\/noindex>, but can others use WebRTC in the same way?<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Thanh Nguyen decided to explore this possibility in his open-source project CloudRetro. CloudRetro is based on Pion, <noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/webrtc-open-source-most-popular\/\">a popular<\/a><\/noindex> WebRTC library in Go (thanks to <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Sean-Der\">Shawn<\/a><\/noindex> from the Pion development team for helping with this article). In this article, Thanh reviews the architecture of his project and shares what insights he gained and the challenges he faced during development.<\/p>\n<h2>Introducere<\/h2>\n<p>\nLast year, when Google announced Stadia, I was blown away. The idea is so unique and innovative that I kept wondering how it was even possible with existing technologies. My desire to understand this topic better led me to create my version of an open-source cloud game. The result was simply fantastic. Below, I would like to share the process of working on my year-long <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">proiectul<\/a><\/noindex>.<\/p>\n<p><i>TLDR: a brief slide version with the main points<\/i><\/p>\n<h3>Why Cloud Gaming is the Future<\/h3>\n<p>\nI believe that Cloud Gaming will soon represent a new generation not only in gaming but also in other areas of IT. Cloud gaming is the pinnacle of the client\/server model. This model maximizes backend management and minimizes frontend workload by placing game logic on a remote server and streaming images\/audio to the client. The server handles heavy processing, so the client is no longer dependent on hardware limitations.<\/p>\n<p>Google Stadia essentially allows you to play <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 games<\/a><\/noindex> (i.e., high-end blockbuster games) on an interface similar to YouTube. The same methodology can be applied to other heavy offline applications, such as operating systems or 2D\/3D graphic design, so we could reliably run them on low-spec devices across different platforms.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/d6ca3e47db5c8e3d9880b304cc3be33b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nThe future of this technology: imagine if Microsoft Windows 10 worked in the Chrome browser?<\/p>\n<h3>Cloud gaming is technically complex<\/h3>\n<p>\nGaming is one of the rare fields where a constant quick response from the user is required. If occasionally there is a delay of 2 seconds when clicking on a page, it's acceptable. Live video streams typically lag a few seconds but still provide sufficient usability. However, if a game often lags by 500 ms, playing becomes impossible. Our goal is to achieve an extremely low latency so that the gap between input and media is as minimal as possible. Therefore, the traditional approach to streaming video is not applicable here.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/d73765a3c9277c026f407883e1091473.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nThe general template for cloud gaming<\/p>\n<h2>The open-source project CloudRetro<\/h2>\n<p>\nI decided to create a test sample of cloud gaming to check if all this is possible under such strict network limitations. For the proof of concept, I chose Golang as it is the most familiar language to me and well-suited for this implementation for many other reasons, as I found out later. Go is simple and develops very quickly; channels in Go are great for managing multithreading.<\/p>\n<p>Proiect <noindex><a rel=\"nofollow\" href=\"http:\/\/cloudretro.io\/\">CloudRetro.io<\/a><\/noindex> \u2013 an open-source cloud gaming service for retro gaming. The goal of the project is to bring the most comfortable gaming experience to traditional retro games and add multiplayer.<br \/>\nYou can find more details about the project here: <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">https:\/\/github.com\/giongto35\/cloud-game<\/a><\/noindex>.<\/p>\n<h3>CloudRetro functionality<\/h3>\n<p>\nTo demonstrate the full power of cloud gaming, CloudRetro uses retro games. This allows for a multitude of unique gaming experiences.<\/p>\n<ul>\n<li>Game portability\n<ul>\n<li>Instant playback upon opening the page; no downloads or installations required<\/li>\n<li>Works in mobile browsers, so no software installation is needed to start<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>Gaming sessions can be shared across multiple devices and stored in the cloud for the next login<\/li>\n<li>The game can be streamed, or multiple users can play it directly:\n<ul>\n<li>Crowdplay like TwitchPlayPokemon, but more cross-platform and real-time<\/li>\n<li>Offline games online. Many users can play without network configuration. In Samurai Shodown, 2 players can now play over the CloudRetro network<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/bdc715971755d669a026f830ce888520.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nA demo version of multiplayer online games on different devices<\/p>\n<h2>Infrastructur\u0103<\/h2>\n<p><\/p>\n<h3>Requirements and technology stack<\/h3>\n<p>\nBelow is a list of requirements that I set before starting the project.<\/p>\n<p><b>1. Un juc\u0103tor<\/b><br \/>\nAceast\u0103 cerin\u021b\u0103 poate p\u0103rea nu foarte important\u0103 \u0219i evident\u0103 aici, dar este una dintre concluziile mele esen\u021biale; permite jocurilor cloud s\u0103 se men\u021bin\u0103 c\u00e2t mai departe de serviciile tradi\u021bionale de streaming. Dac\u0103 ne concentr\u0103m pe jocul solo, putem sc\u0103pa de un server centralizat sau CDN, deoarece nu avem nevoie s\u0103 transmitem informa\u021bii \u00een mas\u0103. \u00cen loc s\u0103 \u00eenc\u0103rc\u0103m fluxuri pe un server care consum\u0103 resurse sau s\u0103 trimitem pachete c\u0103tre un server WebSocket centralizat, fluxurile de servicii sunt transmise utilizatorului direct printr-o conexiune peer-to-peer WebRTC.<\/p>\n<p><b>2. Flux media cu \u00eent\u00e2rziere mic\u0103<\/b><br \/>\nCitind despre Stadia, \u00eent\u00e2lnesc adesea \u00een unele articole men\u021biuni despre WebRTC. Am realizat c\u0103 WebRTC este o tehnologie remarcabil\u0103, perfect\u0103 pentru utilizarea \u00een jocurile cloud. WebRTC este un proiect care ofer\u0103 browserelor web \u0219i aplica\u021biilor mobile comunicare \u00een timp real printr-o API simpl\u0103. Acesta asigur\u0103 o conexiune peer-to-peer, optimizat\u0103 pentru media \u0219i vine cu codec-uri standard \u00eencorporate, cum ar fi VP8 \u0219i H264.<\/p>\n<p>Am preferat asigurarea unei experien\u021be de utilizare c\u00e2t mai confortabile, \u00een locul men\u021binerii unei calit\u0103\u021bi ridicate a graficii. \u00cen algoritm sunt permise unele pierderi. Google Stadia are un pas suplimentar pentru reducerea dimensiunii imaginii pe server, iar cadrele sunt scalate la o calitate mai \u00eenalt\u0103 \u00eenainte de a fi transmise nodurilor peer-to-peer.<\/p>\n<p><b>3. Infrastructur\u0103 distribuit\u0103 cu rutare geografic\u0103<\/b><br \/>\nIndiferent c\u00e2t de optimizat este algoritmul de compresie \u0219i codul, re\u021beaua r\u0103m\u00e2ne un factor decisiv care contribuie cel mai mult la laten\u021b\u0103. Arhitectura trebuie s\u0103 aib\u0103 un mecanism de asociere a celui mai apropiat server utilizatorului pentru a reduce timpul de r\u0103spuns (RTT). Arhitectura trebuie s\u0103 aib\u0103 un coordonator \u0219i mai multe servere de streaming distribuite \u00een \u00eentreaga lume: Vestul SUA, Estul SUA, Europa, Singapore, China. Toate serverele de streaming trebuie s\u0103 fie complet izolate. Sistemul poate ajusta distribu\u021bia sa atunci c\u00e2nd un server se al\u0103tur\u0103 sau p\u0103r\u0103se\u0219te re\u021beaua. Astfel, \u00een cazul unui trafic mare, ad\u0103ugarea de servere suplimentare permite scalarea orizontal\u0103.<\/p>\n<p><b>4. Compatibilitate cu browserul<\/b><br \/>\nJocurile cloud se prezint\u0103 cel mai bine atunci c\u00e2nd necesit\u0103 un minim de efort din partea utilizatorilor. Aceasta \u00eenseamn\u0103 c\u0103 exist\u0103 posibilitatea de a porni direct \u00een browser. Browserele ajut\u0103 la realizarea unei experien\u021be de joc c\u00e2t mai confortabile pentru utilizatori, scutindu-i de instalarea de software \u0219i hardware. De asemenea, browserele contribuie la asigurarea compatibilit\u0103\u021bii \u00eentre platforme pentru versiunile mobile \u0219i desktop. Din fericire, WebRTC este excelent suportat \u00een diverse browsere.<\/p>\n<p><b>5. \u00cemp\u0103r\u021birea clar\u0103 a interfe\u021bei de joc \u0219i a serviciului<\/b><br \/>\nPrivesc serviciul de jocuri cloud ca pe o platform\u0103. Fiecare ar trebui s\u0103 aib\u0103 posibilitatea de a conecta orice la platform\u0103. Acum am integrat <noindex><a rel=\"nofollow\" href=\"http:\/\/LibRetro\">LibRetro<\/a><\/noindex> cu serviciul de jocuri cloud, deoarece LibRetro ofer\u0103 o interfa\u021b\u0103 frumoas\u0103 de emulator de jocuri pentru jocuri retro, cum ar fi SNES, GBA, PS.<\/p>\n<p><b>6. Camere pentru multiplayer, crowd play \u0219i linking extern (deep-link) cu jocul<\/b><br \/>\nCloudRetro suport\u0103 numeroase noi modalit\u0103\u021bi de joc, cum ar fi CrowdPlay \u0219i Multiplayer Online pentru jocuri retro. Dac\u0103 mai mul\u021bi utilizatori deschid acela\u0219i deep-link pe computere diferite, ei vor vedea aceea\u0219i sesiune de joc rulat\u0103 \u0219i pot chiar s\u0103 se al\u0103ture acesteia.<\/p>\n<p>Mai mult, st\u0103rile jocului sunt stocate \u00een cloud. Aceasta permite utilizatorilor s\u0103 continue jocul \u00een orice moment pe orice alt dispozitiv.<\/p>\n<p><b>7. Scalare orizontal\u0103<\/b><br \/>\nCa orice serviciu SAAS \u00een prezent, jocurile cloud trebuie s\u0103 fie concepute pentru a fi scalabile orizontal. Proiectarea \u201ecoordonator-muncitor\u201d permite ad\u0103ugarea de muncitori suplimentari pentru a gestiona un trafic mai mare.<\/p>\n<p><b>8. F\u0103r\u0103 dependen\u021b\u0103 de un singur cloud<\/b><br \/>\nInfrastructura CloudRetro este g\u0103zduit\u0103 pe diferite furnizori de cloud (Digital Ocean, Alibaba, furnizor personalizat) pentru diferite regiuni. Activez pornirea \u00een containere Docker pentru infrastructur\u0103 \u0219i configurez parametrii re\u021belei folosind un script bash, pentru a evita dependen\u021ba de un singur furnizor de cloud. Combin\u00e2nd acest lucru cu NAT Traversal \u00een WebRTC, putem ob\u021bine flexibilitate pentru desf\u0103\u0219urarea CloudRetro pe orice platform\u0103 cloud \u0219i chiar pe ma\u0219inile oric\u0103rui utilizator.<\/p>\n<h3>Design arhitectural<\/h3>\n<p>\n<b>Muncitor:<\/b> (sau serverul de streaming men\u021bionat anterior) multiplic\u0103 jocurile, ini\u021biaz\u0103 procesul de codificare \u0219i transmite media codificat\u0103 utilizatorilor. Instan\u021bele worker sunt distribuite \u00een \u00eentreaga lume, iar fiecare worker poate gestiona mai multe sesiuni ale utilizatorilor simultan.<\/p>\n<p><b>Coordonator:<\/b> responsabil cu asocierea unui nou utilizator cu cel mai potrivit worker pentru streaming. Coordonatorul interac\u021bioneaz\u0103 cu workerele prin WebSocket.<\/p>\n<p><b>Stocarea st\u0103rilor jocurilor:<\/b> un depozit centralizat pentru toate st\u0103rile jocului. Acest depozit ofer\u0103 func\u021bii importante, cum ar fi salvarea\/\u00eenc\u0103rcarea de la distan\u021b\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/985447b81350a640b0bd1344b5705113.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nArhitectura de nivel \u00eenalt pentru CloudRetro<\/p>\n<h3>Scenariul utilizatorului<\/h3>\n<p>\nC\u00e2nd un utilizator nou deschide CloudRetro \u00een pa\u0219ii 1 \u0219i 2, ilustra\u021bi mai jos, coordonatorul \u00eempreun\u0103 cu lista workernelor disponibile este solicitat pe prima pagin\u0103. Dup\u0103 aceea, la pasul 3, clientul calculeaz\u0103 \u00eent\u00e2rzierile pentru to\u021bi candida\u021bii printr-un ping HTTP. Aceast\u0103 list\u0103 de \u00eent\u00e2rzieri este apoi trimis\u0103 \u00eenapoi coordonatorului, astfel \u00eenc\u00e2t acesta s\u0103 poat\u0103 determina cel mai potrivit worker pentru a deservi utilizatorul. La pasul 4, mai jos, se creeaz\u0103 jocul. Se stabile\u0219te o conexiune de streaming WebRTC \u00eentre utilizator \u0219i worker-ul desemnat.<br \/>\n<img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/00199b5942e3e4314609ec0e70ea7162.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nScenariul utilizatorului dup\u0103 ob\u021binerea accesului<\/p>\n<h3>Ce este \u00een interiorul worker-ului<\/h3>\n<p>\nFluxurile de joc \u0219i streaming sunt stocate izolat \u00een interiorul worker-ului \u0219i \u00ee\u0219i schimb\u0103 informa\u021bii printr-o interfa\u021b\u0103. \u00cen prezent, aceast\u0103 comunicare se realizeaz\u0103 prin transmiterea de date \u00een memorie prin <noindex><a rel=\"nofollow\" href=\"https:\/\/tour.golang.org\/concurrency\/2\">canalele Golang<\/a><\/noindex> \u00een acela\u0219i proces. Urm\u0103toarea \u021bint\u0103 este segregarea, adic\u0103 rularea independent\u0103 a jocului \u00eentr-un alt proces.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/7a90ec2638344467a34604cd4322165c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nInterac\u021biunea componentelor worker-ului<\/p>\n<p>Componente de baz\u0103:<\/p>\n<ul>\n<li><b>WebRTC:<\/b> componenta clientului, care accept\u0103 intrarea utilizatorului \u0219i expune media codificat\u0103 de pe server.\n<\/li>\n<li><b>Emulatorul de jocuri:<\/b> componentul de joc. Datorit\u0103 bibliotecii Libretro, sistemul este capabil s\u0103 ruleze jocul \u00een interiorul aceluia\u0219i proces \u0219i s\u0103 intercepteze intern media \u0219i fluxul de intrare.\n<\/li>\n<li>Cadrele din joc sunt capturate \u0219i trimise encoder-ului.\n<\/li>\n<li><b>Encoder de imagine\/audio:<\/b> procesul de codificare care prime\u0219te cadrele media, le codific\u0103 \u00een fundal \u0219i produce imagini\/audio codificate.\n<\/li>\n<\/ul>\n<p><\/p>\n<h2>Implementarea<\/h2>\n<p>\nCloudRetro se bazeaz\u0103 pe WebRTC ca tehnologie de baz\u0103, a\u0219a c\u0103 \u00eenainte de a aprofunda detalii despre implementarea \u00een Golang, am decis s\u0103 vorbesc despre WebRTC \u00een sine. Aceasta este o tehnologie uimitoare, care m-a ajutat enorm s\u0103 ating o \u00eent\u00e2rziere \u00een transmisia datelor de doar c\u00e2teva frac\u021biuni de secund\u0103.<\/p>\n<h3>WebRTC<\/h3>\n<p>\nWebRTC este proiectat pentru a oferi conexiuni peer-to-peer de \u00eenalt\u0103 calitate pe aplica\u021bii mobile native \u0219i \u00een browsere prin intermediul unor API-uri simple.<\/p>\n<h4>Traversare NAT <\/h4>\n<p>\nWebRTC este cunoscut pentru func\u021bionalitatea sa de NAT Traversal. WebRTC este destinat comunic\u0103rii peer-to-peer. Scopul s\u0103u este s\u0103 g\u0103seasc\u0103 cea mai potrivit\u0103 cale direct\u0103, evit\u00e2nd gateway-urile NAT \u0219i firewalls pentru comunicare peer-to-peer printr-un proces numit <noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/trickle-ice\/\">ICE<\/a><\/noindex>. \u00cen cadrul acestui proces, API-urile WebRTC \u00ee\u0219i g\u0103sesc adresa IP public\u0103 prin servere STUN \u0219i o redirec\u021bioneaz\u0103 c\u0103tre un server de retransmisie (<noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/?s=turn\">TURN<\/a><\/noindex>), atunci c\u00e2nd nu se poate stabili o conexiune direct\u0103.<\/p>\n<p>Cu toate acestea, CloudRetro nu folose\u0219te complet aceast\u0103 capacitate. Conexiunile sale peer-to-peer nu exist\u01ce \u00eentre utilizatori, ci \u00eentre utilizatori \u0219i servere cloud. Partea serverului modelului are mai pu\u021bine restric\u021bii privind comunica\u021bia direct\u0103 dec\u00e2t un dispozitiv obi\u015fnuit utilizator. Acest lucru permite deschiderea prealabil\u0103 a porturilor de intrare sau utilizarea adreselor IP publice direct, deoarece serverul nu se afl\u0103 \u00een spatele unui NAT.<\/p>\n<p>\u00cen trecut, am dorit s\u0103 transform proiectul \u00eentr-o platform\u0103 de distribu\u021bie a jocurilor pentru Cloud Gaming. Ideea era de a permite creatorilor de jocuri s\u0103 ofere jocuri \u0219i resurse de streaming. Iar utilizatorii ar interac\u021biona direct cu furnizorii. \u00centr-un mod descentralizat, CloudRetro este doar un mediu pentru conectarea resurselor externe de streaming la utilizatori, ceea ce \u00eel face mai scalabil, deoarece nu se mai ocup\u0103 de hosting. Rolul NAT Traversal al WebRTC este foarte important pentru facilitarea ini\u021bierii conexiunii peer-to-peer pe resurse externe de streaming, ceea ce simplific\u0103 conectarea creatorului la re\u021bea.<\/p>\n<h4>compresia video<\/h4>\n<p>\nCompresia video este o parte esen\u021bial\u0103 a fluxului de lucru, care contribuie semnificativ la fluiditatea stream-ului. De\u0219i nu este necesar s\u0103 cunoa\u0219te\u021bi toate detaliile de codare video \u00een VP8\/H264, \u00een\u021belegerea conceptului ajut\u0103 la gestionarea parametrilor de vitez\u0103 ai video-ului streaming, la depanarea comportamentului nea\u0219teptat \u0219i la ajustarea \u00eent\u00e2rzierii.<\/p>\n<p>Compresia video pentru servicii de streaming reprezint\u0103 o provocare complex\u0103, deoarece algoritmul trebuie s\u0103 garanteze c\u0103 timpul total de codare + timpul de transmisie pe re\u021bea + timpul de decodare este c\u00e2t mai mic posibil. \u00cen plus, procesul de codare trebuie s\u0103 fie consecvent \u0219i continuu. Unele compromisuri \u00een codare nu se aplic\u0103 \u2013 de exemplu, nu putem prefera un timp de codare mai lung pentru un fi\u0219ier mai mic \u0219i un timp de decodare mai mic sau s\u0103 folosim compresie neregulat\u0103.<\/p>\n<p>Ideea compresiei video const\u0103 \u00een eliminarea bitilor inutili de informa\u021bie, p\u0103str\u00e2nd \u00een acela\u0219i timp un nivel acceptabil de exactitate pentru utilizatori. Pe l\u00e2ng\u0103 codarea cadrelor statice individuale ale imaginii, algoritmul deduce pentru cadrul curent din cadrelor anterioare \u0219i urm\u0103toare, a\u0219a c\u0103 se trimite doar diferen\u021ba dintre acestea. A\u0219a cum se poate observa \u00een exemplul cu Pacman, se transmit doar punctele diferen\u021biale.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/e452c54c53ab7797b610620aefbba8d2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nCompara\u021bia cadrelor video \u00een exemplul Pacman<\/p>\n<h4>Compresia audio<\/h4>\n<p>\n\u00cen mod similar, algoritmul de compresie a sunetului omite datele care nu pot fi percepute de oameni. Opus este \u00een prezent codec-ul audio cu cea mai bun\u0103 performan\u021b\u0103. Acesta este dezvoltat pentru a transmite unda audio printr-un protocol de datagrame ordonate, cum ar fi RTP (Real Time Transport Protocol \u2013 protocol de transport de date \u00een timp real). \u00cent\u00e2rzierea sa este mai mic\u0103 dec\u00e2t cea a mp3 \u0219i aac, iar calitatea este superioar\u0103. \u00cent\u00e2rzierea este \u00een general de aproximativ 5~66,5 ms.<\/p>\n<h4>Pion, WebRTC \u00een Golang<\/h4>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pion\/webrtc\">Pion<\/a><\/noindex> \u2013 este un proiect cu surs\u0103 deschis\u0103 care \u00eembun\u0103t\u0103\u021be\u0219te WebRTC pe Golang. \u00cen loc de a \u00eenv\u00e2rti biblioteci native C++ WebRTC, Pion este o implementare nativ\u0103 Golang a WebRTC cu performan\u021be superioare, integrare cu Go \u0219i control al versiunilor pe protocoalele WebRTC.<\/p>\n<p>Biblioteca ofer\u0103, de asemenea, streaming de date cu numeroase module excelente \u00eencorporate, cu o \u00eent\u00e2rziere de mai pu\u021bin de o secund\u0103. Are propriile sale implement\u0103ri STUN, DTLS, SCTP etc. \u0219i unele experimente cu QUIC \u0219i WebAssembly. Aceast\u0103 bibliotec\u0103 open-source este cu adev\u0103rat o surs\u0103 bun\u0103 de \u00eenv\u0103\u021bare, av\u00e2nd o documenta\u021bie excelent\u0103, implement\u0103ri de protocoale de re\u021bea \u0219i exemple interesante.<\/p>\n<p>Comunitatea Pion, condus\u0103 de un creator foarte pasionat, este destul de activ\u0103, av\u00e2nd multe discu\u021bii de calitate despre WebRTC. Dac\u0103 sunte\u021bi interesat de aceast\u0103 tehnologie, al\u0103tura\u021bi-v\u0103 <noindex><a rel=\"nofollow\" href=\"http:\/\/pion.ly\/slack\">http:\/\/pion.ly\/slack<\/a><\/noindex> \u2013 ve\u021bi \u00eenv\u0103\u021ba multe lucruri noi.<\/p>\n<h3>Scrierea CloudRetro \u00een Golang<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/f85f7b8ea579fab964d870aad698c7e7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nImplementarea unui worker \u00een Go<\/p>\n<h4>Canalele Go \u00een ac\u021biune<\/h4>\n<p>\nDatorit\u0103 designului elegant al canalelor Go, problemele legate de streaming-ul evenimentelor \u0219i paralelism sunt semnificativ simplificate. A\u0219a cum se vede \u00een diagram\u0103, mai multe componente func\u021bioneaz\u0103 \u00een paralel \u00een diferite GoRoutines. Fiecare component\u0103 \u00ee\u0219i gestioneaz\u0103 propriul stare \u0219i comunic\u0103 prin canale. Afirmarea selectiv\u0103 \u00een Golang determin\u0103 procesarea unui singur eveniment atomic la fiecare moment \u00een joc (game tick). Acest lucru \u00eenseamn\u0103 c\u0103 pentru un astfel de design nu este nevoie de blocare. De exemplu, atunci c\u00e2nd un utilizator salveaz\u0103, este necesar un snapshot complet al st\u0103rii jocului. Aceast\u0103 stare trebuie s\u0103 r\u0103m\u00e2n\u0103 consecvent\u0103, execut\u00e2nd intr\u0103ri p\u00e2n\u0103 c\u00e2nd salvarea este complet\u0103. \u00cen timpul fiec\u0103rui game tick, backend-ul poate procesa doar opera\u021bia de salvare sau de intrare, f\u0103c\u00e2nd procesul sigur pentru multithreading.<\/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>\nAcest \u0219ablon Golang se potrive\u0219te perfect pentru cazul meu de utilizare CrowdPlay \u0219i Multiple Player. Urm\u00e2nd acest \u0219ablon, toate intr\u0103rile utilizatorilor dintr-o camer\u0103 sunt integrate \u00eentr-un canal de intrare central. Media de joc este apoi distribuit\u0103 tuturor utilizatorilor dintr-o camer\u0103. Astfel, ob\u021binem separarea st\u0103rii jocului \u00eentre mai multe sesiuni de joc ale diferitelor utilizatori.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103\" src=\"\/wp-content\/uploads\/2020\/07\/000a495d7f214246a8a396aab11a3ac5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSincronizarea \u00eentre sesiuni diferite<\/p>\n<h4>Dezavantajele Golang<\/h4>\n<p>\nGolang nu este perfect. Canalul este lent. Comparativ cu blocajul, canalul Go este pur \u0219i simplu o modalitate mai simpl\u0103 de a gestiona evenimentele paralele \u0219i de flux, dar canalul nu ofer\u0103 cea mai bun\u0103 performan\u021b\u0103. Sub canal exist\u0103 o logic\u0103 complex\u0103 de blocare. Prin urmare, am f\u0103cut unele ajust\u0103ri \u00een implementare, reutiliz\u00e2nd bloc\u0103rile \u0219i valorile atomice atunci c\u00e2nd am \u00eenlocuit canalele pentru a optimiza performan\u021ba.<\/p>\n<p>\u00cen plus, garbage collector-ul din Golang este necontrolat, ceea ce poate duce la pauze suspect de lungi. Acest lucru interfereaz\u0103 semnificativ cu func\u021bionarea aplica\u021biilor de streaming \u00een timp real.<\/p>\n<h4>CGO<\/h4>\n<p>\n\u00cen proiect este utilizat\u0103 o bibliotec\u0103 existent\u0103 VP8\/H264 Golang cu surs\u0103 deschis\u0103 pentru comprimarea mediei \u0219i Libretro pentru emulatorii de jocuri. Toate aceste biblioteci sunt pur \u0219i simplu wrapper-uri ale bibliotecii C \u00een Go utiliz\u00e2nd <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/cmd\/cgo\/\">CGO<\/a><\/noindex>. Unele dintre dezavantaje sunt enumerate \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/dave.cheney.net\/2019\/10\/06\/use-internal-packages-to-reduce-your-public-api-surface\">aceast\u0103 postare a lui Dave Cheney<\/a><\/noindex>. Problemele cu care m-am confruntat sunt:<\/p>\n<ul>\n<li>imposibilitatea de a captura crash-uri \u00een CGO, chiar \u0219i cu ajutorul Golang RecoveryCrash;<\/li>\n<li>imposibilitatea de a identifica un punct limit\u0103 \u00een performan\u021b\u0103, atunci c\u00e2nd nu putem detecta problemele detaliate \u00een CGO.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Concluzie<\/h2>\n<p>\nAm atins obiectivul meu \u2013 am \u00een\u021beles serviciile de jocuri \u00een cloud \u0219i am creat o platform\u0103 care ajut\u0103 la jocul retro cu prietenii mei online. Crearea acestui proiect nu ar fi fost posibil\u0103 f\u0103r\u0103 biblioteca Pion \u0219i suportul comunit\u0103\u021bii Pion. Sunt extrem de recunosc\u0103tor pentru dezvoltarea sa intens\u0103. API-urile simple oferite de WebRTC \u0219i Pion au asigurat o integrare lin\u0103. Prima mea dovad\u0103 a conceptului a fost lansat\u0103 \u00een aceea\u0219i s\u0103pt\u0103m\u00e2n\u0103, de\u0219i nu \u0219tiam anterior despre conectivitatea peer-to-peer (P2P).<\/p>\n<p>\u00cen ciuda simplit\u0103\u021bii integr\u0103rii, streamingul P2P este \u00eentr-adev\u0103r un domeniu foarte complex \u00een \u0219tiin\u021ba computerelor. Trebuie s\u0103 se confrunte cu complexitatea arhitecturilor de re\u021bea \u00eendelungate, cum ar fi IP \u0219i NAT, pentru a crea o sesiune peer-to-peer. Pe parcursul lucrului la acest proiect, am acumulat multe cuno\u0219tin\u021be valoroase despre re\u021bea \u0219i optimizarea performan\u021bei, a\u0219a c\u0103 recomand tuturor s\u0103 \u00eencerce s\u0103 construiasc\u0103 produse P2P folosind WebRTC.<\/p>\n<p>CloudRetro satisface toate scenariile de utilizare pe care le a\u0219teptam, din perspectiva mea de retro-gamer. Totu\u0219i, cred c\u0103 exist\u0103 multe domenii \u00een proiect pe care le pot \u00eembun\u0103t\u0103\u021bi, cum ar fi cre\u0219terea fiabilit\u0103\u021bii \u0219i performan\u021bei re\u021belei, asigurarea unei calit\u0103\u021bi mai bune a graficii jocurilor sau posibilitatea de a partaja jocuri \u00eentre utilizatori. Lucrez din greu la asta. V\u0103 rog s\u0103 urm\u0103ri\u021bi <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">proiectul<\/a><\/noindex> \u0219i s\u0103-l sus\u021bine\u021bi dac\u0103 v\u0103 place.<\/li>\n<\/ul>\n<p>Sursa: <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.3 - 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\/ro\/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.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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\/ro\/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\udd47Jocuri \u00een cloud cu surs\u0103 deschis\u0103 pe WebRTC: p2p, multiplayer, zero laten\u021b\u0103 | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/ro\/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":"ro_RO","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\/ro\/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\/ro\/wp-json\/wp\/v2\/posts\/89303","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=89303"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/89303\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/89304"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=89303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=89303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=89303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}