{"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\/it\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency","title":{"rendered":"Gaming cloud open source su 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=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/22dbf7665d7fded15671d98a2afe599b.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\nIl cloud come servizio, l'infrastruttura come servizio, la piattaforma come servizio, la piattaforma di comunicazione come servizio, le videoconferenze come servizio, e che dire del cloud gaming come servizio? Sono gi\u00e0 stati fatti diversi tentativi per creare giochi in cloud (Cloud Gaming), ad esempio Stadia, recentemente lanciata da Google. Stadia <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/avtlQeaxd_I?t=440\">non \u00e8 nuova in WebRTC<\/a><\/noindex>, ma possono gli altri utilizzare WebRTC allo stesso modo?<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Thanh Nguyen ha deciso di testare questa possibilit\u00e0 nel suo progetto open source CloudRetro. CloudRetro \u00e8 basato su Pion, <noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/webrtc-open-source-most-popular\/\">una popolare<\/a><\/noindex> libreria WebRTC basata su Go (grazie a <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/Sean-Der\">Sean<\/a><\/noindex> del gruppo di sviluppatori Pion per l'aiuto nella preparazione di questo articolo). In questo articolo, Thanh fornisce una panoramica dell'architettura del suo progetto e condivide ci\u00f2 che ha trovato utile e le sfide affrontate durante il lavoro.<\/p>\n<h2>Introduzione<\/h2>\n<p>\nL'anno scorso, quando Google ha annunciato Stadia, sono rimasto completamente sbalordito. L'idea \u00e8 cos\u00ec unica e innovativa che mi sono costantemente chiesto come fosse possibile con le tecnologie attuali. Il desiderio di comprendere meglio questo tema mi ha spinto a creare la mia versione di un gioco in cloud open source. Il risultato \u00e8 stato semplicemente fantastico. Vorrei condividere di seguito il processo di lavoro sul mio progetto annuale <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">progetto<\/a><\/noindex>.<\/p>\n<p><i>TLDR: versione breve con i punti principali<\/i><\/p>\n<h3>Perch\u00e9 il futuro appartiene ai giochi in cloud<\/h3>\n<p>\nCredo che il Cloud Gaming diventer\u00e0 presto una nuova generazione non solo di giochi, ma anche in altri ambiti dell'informatica. I giochi in cloud rappresentano il culmine del modello client\/server. Questo modello massimizza la gestione del backend e minimizza il lavoro sul frontend, collocando la logica di gioco su un server remoto e trasmettendo le immagini\/audio al cliente. Il server esegue l'elaborazione pesante, quindi il cliente non \u00e8 pi\u00f9 vincolato alle limitazioni hardware.<\/p>\n<p>Google Stadia, in sostanza, permette di giocare a <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)\">giochi AAA<\/a><\/noindex> (cio\u00e8 giochi blockbuster di alta qualit\u00e0) su un'interfaccia simile a YouTube. La stessa metodologia pu\u00f2 essere applicata ad altre applicazioni pesanti offline, come un sistema operativo o il design grafico 2D\/3D, ecc., in modo che possiamo eseguirle stabilmente su dispositivi con caratteristiche tecniche basse su diverse piattaforme.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/d6ca3e47db5c8e3d9880b304cc3be33b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIl futuro di questa tecnologia: immaginate se Microsoft Windows 10 funzionasse nel browser Chrome?<\/p>\n<h3>I giochi in cloud sono tecnicamente complessi<\/h3>\n<p>\nIl gaming \u00e8 uno di quei rari settori in cui \u00e8 necessaria una reazione rapida e costante da parte dell'utente. Se occasionalmente ci troviamo con un ritardo di 2 secondi al clic su una pagina, questo \u00e8 accettabile. I flussi video in diretta tendono a ritardare di alcuni secondi, ma offrono comunque una comodit\u00e0 sufficiente. Tuttavia, se un gioco ha frequentemente un ritardo di 500 ms, giocare diventa semplicemente impossibile. Il nostro obiettivo \u00e8 raggiungere una latenza estremamente bassa affinch\u00e9 la disconnessione tra l'input e i media sia la minore possibile. Pertanto, l'approccio tradizionale allo streaming video non \u00e8 applicabile qui.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/d73765a3c9277c026f407883e1091473.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nModello generale di gioco in cloud<\/p>\n<h2>Progetto open source CloudRetro<\/h2>\n<p>\nHo deciso di creare un campione di prova di gioco in cloud per verificare se tutto ci\u00f2 fosse possibile con restrizioni di rete cos\u00ec severe. Per testare il concetto, ho scelto Golang, poich\u00e9 \u00e8 il linguaggio a me pi\u00f9 familiare e si adatta bene a questa implementazione per molti altri motivi, come scoperto in seguito. Go \u00e8 semplice e si sviluppa molto rapidamente; i canali in Go sono ottimi per gestire la multithreading.<\/p>\n<p>Progetto <noindex><a rel=\"nofollow\" href=\"http:\/\/cloudretro.io\/\">CloudRetro.io<\/a><\/noindex> \u2013 servizio di gioco in cloud open source per giochi retro. L'obiettivo del progetto \u00e8 portare nelle tradizionali esperienze di gioco retro la massima comodit\u00e0 possibile e aggiungere il multiplayer.<br \/>\nPuoi trovare ulteriori dettagli sul progetto qui: <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">https:\/\/github.com\/giongto35\/cloud-game<\/a><\/noindex>.<\/p>\n<h3>Funzionalit\u00e0 di CloudRetro<\/h3>\n<p>\nPer dimostrare tutta la potenza dei giochi in cloud, su CloudRetro vengono utilizzati giochi retro. Questo consente di ottenere molte esperienze di gioco uniche.<\/p>\n<ul>\n<li>Portabilit\u00e0 del gioco\n<ul>\n<li>Riproduzione istantanea all'apertura della pagina; non \u00e8 necessaria alcuna installazione o download<\/li>\n<li>Funziona nel browser mobile, quindi non \u00e8 necessario alcun software per avviarlo<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>Le sessioni di gioco possono essere condivise su pi\u00f9 dispositivi e memorizzate nel cloud per accessi futuri<\/li>\n<li>Il gioco pu\u00f2 essere trasmesso in streaming ed essere giocato da pi\u00f9 utenti contemporaneamente:\n<ul>\n<li>Crowdplay tipo TwitchPlayPokemon, solo pi\u00f9 cross-platform e pi\u00f9 in tempo reale<\/li>\n<li>Gioco offline in online. Molti utenti possono giocare senza alcuna configurazione di rete. In Samurai Shodown \u00e8 ora possibile giocare a 2 giocatori attraverso la rete CloudRetro<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/bdc715971755d669a026f830ce888520.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDemo di un gioco online multiplayer su dispositivi diversi<\/p>\n<h2>Infrastruttura<\/h2>\n<p><\/p>\n<h3>Requisiti e stack tecnologici<\/h3>\n<p>\nDi seguito \u00e8 riportato un elenco dei requisiti che ho stabilito prima di iniziare il progetto.<\/p>\n<p><b>1. Un giocatore<\/b><br \/>\nQuesta richiesta potrebbe sembrare non troppo importante e ovvia qui, ma \u00e8 una delle mie conclusioni chiave, consente ai giochi cloud di rimanere il pi\u00f9 lontano possibile dai tradizionali servizi di streaming. Se ci concentriamo sul gioco per un singolo giocatore, possiamo eliminare un server centralizzato o un CDN, poich\u00e9 non abbiamo bisogno di trasmettere a masse. Invece di caricare i flussi su un server inghiottitore o inviare pacchetti a un server WebSocket centralizzato, i flussi di servizio vengono inviati direttamente all'utente tramite una connessione peer-to-peer WebRTC.<\/p>\n<p><b>2. Flusso media a bassa latenza<\/b><br \/>\nLeggendo di Stadia, incontro spesso in alcuni articoli il riferimento a WebRTC. Ho capito che WebRTC \u00e8 una tecnologia eccezionale, ed \u00e8 perfetta per l'uso nei giochi cloud. WebRTC \u00e8 un progetto che fornisce a browser web e applicazioni mobili comunicazione in tempo reale tramite un'interfaccia API semplice. Fornisce una connessione peer-to-peer, ottimizzata per i media e ha codec standard integrati, come VP8 e H264.<\/p>\n<p>Ho dato priorit\u00e0 a garantire il massimo comfort per gli utenti, piuttosto che mantenere un'alta qualit\u00e0 grafica. Nell'algoritmo sono ammesse alcune perdite. In Google Stadia c'\u00e8 un passaggio aggiuntivo per ridurre le dimensioni dell'immagine sul server, e i frame vengono scalati a una qualit\u00e0 pi\u00f9 alta prima di essere inviati ai nodi peer-to-peer.<\/p>\n<p><b>3. Infrastruttura distribuita con routing geografico<\/b><br \/>\nIndipendentemente da quanto sia ottimizzato l'algoritmo di compressione e il codice, la rete rimane comunque un fattore determinante che contribuisce maggiormente alla latenza. L'architettura deve avere un meccanismo di accoppiamento del server pi\u00f9 vicino all'utente per ridurre il tempo di andata e ritorno (RTT). L'architettura deve avere 1 coordinatore e diversi server di streaming distribuiti in tutto il mondo: Ovest degli Stati Uniti, Est degli Stati Uniti, Europa, Singapore, Cina. Tutti i server di streaming devono essere completamente isolati. Il sistema pu\u00f2 regolare la sua distribuzione quando un server si unisce alla rete o ne esce. Cos\u00ec, con un alto traffico, l'aggiunta di server supplementari permette di realizzare una scalabilit\u00e0 orizzontale.<\/p>\n<p><b>4. Compatibilit\u00e0 del browser<\/b><br \/>\nI giochi in cloud si presentano al meglio quando richiedono il minimo agli utenti. Questo significa che c'\u00e8 la possibilit\u00e0 di avviarli nel browser. I browser aiutano a rendere il processo di gioco il pi\u00f9 confortevole possibile per gli utenti, liberandoli dall'installazione di software e hardware. I browser aiutano anche a garantire la compatibilit\u00e0 cross-platform per le versioni mobili e desktop. Fortunatamente, WebRTC \u00e8 ben supportato in vari browser.<\/p>\n<p><b>5. Chiarezza nella separazione dell'interfaccia di gioco e del servizio<\/b><br \/>\nConsidero il servizio di giochi in cloud come una piattaforma. Ognuno dovrebbe avere la possibilit\u00e0 di collegarsi alla piattaforma per qualsiasi cosa. Attualmente ho integrato <noindex><a rel=\"nofollow\" href=\"http:\/\/LibRetro\">LibRetro<\/a><\/noindex> con il servizio di giochi in cloud, perch\u00e9 LibRetro offre una bella interfaccia di emulatore di gioco per giochi retro, come SNES, GBA, PS.<\/p>\n<p><b>6. Stanze per il multiplayer, crowd play e collegamento esterno (deep-link) con il gioco<\/b><br \/>\nCloudRetro supporta molti nuovi stili di gioco, come CrowdPlay e Online MultiPlayer per giochi retro. Se pi\u00f9 utenti aprono lo stesso deep-link su computer diversi, vedranno lo stesso gioco avviato e potranno persino unirsi a esso.<\/p>\n<p>Inoltre, gli stati di gioco vengono memorizzati nel cloud. Questo consente agli utenti di continuare a giocare in qualsiasi momento su qualsiasi altro dispositivo.<\/p>\n<p><b>7. Scalabilit\u00e0 orizzontale<\/b><br \/>\nCome qualsiasi SAAS al giorno d'oggi, i giochi in cloud devono essere progettati per essere orizzontalmente scalabili. La struttura \"coordinatore-lavoratore\" consente di aggiungere pi\u00f9 lavoratori per gestire un volume maggiore di traffico.<\/p>\n<p><b>8. Nessun vincolo a un solo cloud<\/b><br \/>\nL'infrastruttura di CloudRetro \u00e8 situata su diversi fornitori di cloud (Digital Ocean, Alibaba, fornitore personalizzato) per varie regioni. Attivo il lancio in contenitore Docker per l'infrastruttura e configuro i parametri di rete tramite uno script bash, per evitare dipendenze da un solo fornitore di cloud. Combinando ci\u00f2 con il NAT Traversal in WebRTC, possiamo ottenere flessibilit\u00e0 per implementare CloudRetro su qualsiasi piattaforma cloud e anche su computer di qualsiasi utente.<\/p>\n<h3>Progettazione architettonica<\/h3>\n<p>\n<b>Lavoratore:<\/b> (o il server di streaming menzionato sopra) moltiplica i giochi, avvia la pipeline di codifica e trasmette media codificati agli utenti. Le istanze del worker sono distribuite in tutto il mondo e ogni worker pu\u00f2 gestire pi\u00f9 sessioni utente contemporaneamente.<\/p>\n<p><b>Coordinatore:<\/b> si occupa di abbinare il nuovo utente con il worker pi\u00f9 appropriato per lo streaming. Il coordinatore interagisce con i worker tramite WebSocket.<\/p>\n<p><b>Archiviazione degli stati di gioco:<\/b> archivio remoto centrale per tutti gli stati di gioco. Questo archivio fornisce funzioni importanti come il salvataggio\/caricamento remoto.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/985447b81350a640b0bd1344b5705113.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nArchitettura di alto livello di CloudRetro<\/p>\n<h3>Scenario utente<\/h3>\n<p>\nQuando un nuovo utente apre CloudRetro nei passaggi 1 e 2 mostrati nell'immagine sottostante, il coordinatore, insieme all'elenco dei worker disponibili, viene richiesto alla prima pagina. Successivamente, nel passo 3, il cliente calcola i ritardi per tutti i candidati tramite una richiesta HTTP ping. Questo elenco di ritardi viene quindi inviato di nuovo al coordinatore, che pu\u00f2 determinare il worker pi\u00f9 adatto per assistere l'utente. Nel passo 4 sottostante viene creata una partita. Viene stabilita una connessione streaming WebRTC tra l'utente e il worker assegnato.<br \/>\n<img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/00199b5942e3e4314609ec0e70ea7162.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nScenario utente dopo aver ottenuto accesso<\/p>\n<h3>Cosa c'\u00e8 dentro il worker<\/h3>\n<p>\nLe pipeline di gioco e streaming sono archiviate all'interno del worker in modo isolato e scambiano informazioni l\u00ec tramite un'interfaccia. Attualmente, questa comunicazione avviene mediante il trasferimento di dati in memoria attraverso <noindex><a rel=\"nofollow\" href=\"https:\/\/tour.golang.org\/concurrency\/2\">canali Golang<\/a><\/noindex> nello stesso processo. Il prossimo obiettivo \u00e8 la segregazione, ovvero l'esecuzione indipendente del gioco in un altro processo.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/7a90ec2638344467a34604cd4322165c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nInterazione dei componenti del worker<\/p>\n<p>Componenti principali:<\/p>\n<ul>\n<li><b>WebRTC:<\/b> componente client, che riceve l'input dell'utente e restituisce media codificati dal server.\n<\/li>\n<li><b>Emulatore di gioco:<\/b> componente di gioco. Grazie alla libreria Libretro, il sistema \u00e8 in grado di eseguire il gioco all'interno dello stesso processo e di intercettare internamente media e flussi di input.\n<\/li>\n<li>Le immagini\/il video vengono catturati e inviati al codificatore.\n<\/li>\n<li><b>Codificatore di immagini\/audio:<\/b> pipeline di codifica che riceve i frame media, li codifica in background e restituisce immagini\/audio codificati.\n<\/li>\n<\/ul>\n<p><\/p>\n<h2>Implementazione<\/h2>\n<p>\nCloudRetro si basa su WebRTC come tecnologia principale, quindi prima di addentrarmi nei dettagli dell'implementazione in Golang, ho deciso di parlare di WebRTC stesso. \u00c8 una tecnologia straordinaria che mi ha molto aiutato a raggiungere un ritardo nella trasmissione dei dati pari a solo una frazione di secondo.<\/p>\n<h3>WebRTC<\/h3>\n<p>\nWebRTC \u00e8 progettato per garantire connessioni peer-to-peer di alta qualit\u00e0 su applicazioni mobili native e browser tramite semplici API.<\/p>\n<h4>NAT Traversal <\/h4>\n<p>\nWebRTC \u00e8 noto per la sua funzionalit\u00e0 di NAT Traversal. WebRTC \u00e8 progettato per la comunicazione peer-to-peer. Il suo obiettivo \u00e8 trovare il percorso diretto pi\u00f9 adatto evitando gateway NAT e firewall per la comunicazione peer-to-peer attraverso un processo chiamato <noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/trickle-ice\/\">ICE<\/a><\/noindex>. Nell'ambito di questo processo, le API di WebRTC trovano il tuo indirizzo IP pubblico utilizzando server STUN e lo reindirizzano a un server di relay (<noindex><a rel=\"nofollow\" href=\"https:\/\/webrtchacks.com\/?s=turn\">TURN<\/a><\/noindex>), quando non \u00e8 possibile stabilire una connessione diretta.<\/p>\n<p>Tuttavia, CloudRetro non sfrutta completamente questa possibilit\u00e0. Le sue connessioni peer-to-peer non esistono tra utenti, ma tra utenti e server cloud. La parte server del modello ha meno restrizioni sulla connessione diretta rispetto a un normale dispositivo utente. Ci\u00f2 consente l'apertura anticipata delle porte in entrata o l'uso diretto di indirizzi IP pubblici, poich\u00e9 il server non si trova dietro un NAT.<\/p>\n<p>In passato volevo trasformare il progetto in una piattaforma di distribuzione giochi per Cloud Gaming. L'idea era di permettere ai creatori di giochi di fornire giochi e risorse di streaming. E gli utenti interagirebbero direttamente con i fornitori. In questo modo decentralizzato, CloudRetro \u00e8 semplicemente un ambiente per collegare risorse di streaming di terze parti agli utenti, rendendolo pi\u00f9 scalabile, poich\u00e9 non \u00e8 pi\u00f9 vincolato all'hosting. Il ruolo del NAT Traversal di WebRTC \u00e8 qui molto importante per facilitare l'inizializzazione di una connessione peer-to-peer su risorse di streaming di terze parti, semplificando la connessione tra il creatore e la rete.<\/p>\n<h4>Compressione video<\/h4>\n<p>\nLa compressione video \u00e8 una parte indispensabile del pipeline, che contribuisce in modo significativo alla fluidit\u00e0 del flusso. Sebbene non sia necessario conoscere tutti i dettagli della codifica video in VP8\/H264, comprendere il concetto aiuta a gestire i parametri di bitrate del video in streaming, a debuggare comportamenti imprevisti e a regolare la latenza.<\/p>\n<p>La compressione video per un servizio di streaming \u00e8 un compito complesso, perch\u00e9 l'algoritmo deve garantire che il tempo totale di codifica + tempo di trasmissione in rete + tempo di dekodifica sia il pi\u00f9 ridotto possibile. Inoltre, il processo di codifica deve essere coerente e continuo. Alcuni compromessi nel processo di codifica non sono applicabili: ad esempio, non possiamo preferire un lungo tempo di codifica a un file di dimensioni ridotte e a un tempo di dekodifica minore, o utilizzare una compressione incoerente.<\/p>\n<p>L'idea della compressione video consiste nell'escludere i bit di informazioni non necessari, mantenendo al contempo un livello accettabile di accuratezza per gli utenti. Oltre a codificare singoli fotogrammi statici, l'algoritmo deduce il fotogramma corrente da quello precedente e successivo, quindi invia solo la loro differenza. Come si pu\u00f2 vedere nell'esempio con Pacman, vengono trasmesse solo le differenze.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/e452c54c53ab7797b610620aefbba8d2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nConfronto dei fotogrammi video con Pacman<\/p>\n<h4>Compressione audio<\/h4>\n<p>\nIn modo analogo, l'algoritmo di compressione audio elimina i dati che non possono essere percepiti dall'orecchio umano. Attualmente, Opus \u00e8 il codec audio con le migliori prestazioni. \u00c8 stato progettato per trasmettere onde audio tramite protocolli di datagramma ordinati, come RTP (Real Time Transport Protocol \u2013 protocollo di trasporto in tempo reale). La sua latenza \u00e8 inferiore a quella di mp3 e aac, e la qualit\u00e0 \u00e8 superiore. La latenza \u00e8 di solito di circa 5~66,5 ms.<\/p>\n<h4>Pion, WebRTC in Golang<\/h4>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pion\/webrtc\">Pion<\/a><\/noindex> \u00e8 un progetto open source che porta WebRTC in Golang. Invece di avvolgere le librerie C++ native di WebRTC, Pion \u00e8 un'implementazione nativa di WebRTC in Golang che offre migliori prestazioni, integrazione con Go e anche un controllo delle versioni sui protocolli WebRTC.<\/p>\n<p>La libreria offre anche uno streaming di dati con un gran numero di eccellenti moduli integrati con una latenza di meno di un secondo. Ha la propria implementazione di STUN, DTLS, SCTP, ecc. e alcuni esperimenti con QUIC e WebAssembly. Questa libreria open source \u00e8 davvero una buona fonte didattica con ottima documentazione, implementazione di protocolli di rete e casi di studio interessanti.<\/p>\n<p>La comunit\u00e0 Pion, guidata da un creatore molto appassionato, \u00e8 piuttosto vivace, con molte discussioni di qualit\u00e0 su WebRTC. Se sei interessato a questa tecnologia, unisciti a <noindex><a rel=\"nofollow\" href=\"http:\/\/pion.ly\/slack\">http:\/\/pion.ly\/slack<\/a><\/noindex> \u2013 imparerai molte cose nuove.<\/p>\n<h3>Scrivere CloudRetro in Golang<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/f85f7b8ea579fab964d870aad698c7e7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nImplementazione di un worker in Go<\/p>\n<h4>Canali Go in azione<\/h4>\n<p>\nGrazie al design elegante dei canali Go, le problematiche di streaming di eventi e parallelismo sono notevolmente semplificate. Come mostrato nel diagramma, diversi componenti lavorano in parallelo in diverse GoRoutines. Ogni componente gestisce il proprio stato e comunica attraverso i canali. La selezione condizionale di Golang richiede di trattare un singolo evento atomico alla volta durante ogni momento del gioco (game tick). Questo significa che per un tale design non \u00e8 necessaria alcuna sincronizzazione. Ad esempio, quando un utente salva, \u00e8 necessario avere un snapshot completo dello stato del gioco. Questo stato deve rimanere continuo mentre il login \u00e8 attivo fino al completamento del salvataggio. Durante ciascun game tick, il backend pu\u00f2 gestire solo l'operazione di salvataggio o di input, rendendo il processo thread-safe.<\/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>\nQuesto modello Golang si adatta perfettamente al mio caso d'uso di CrowdPlay e Multiplayer. Seguendo questo modello, tutti gli input degli utenti in una stanza vengono incanalati in un canale di ingresso centrale. I media di gioco vengono quindi distribuiti a tutti gli utenti nella stessa stanza. In questo modo, ci si assicura di condividere lo stato del gioco tra diverse sessioni di gioco degli utenti.<\/p>\n<p><img decoding=\"async\" alt=\"Gaming cloud open source su WebRTC: p2p, multiplayer, zero latency\" src=\"\/wp-content\/uploads\/2020\/07\/000a495d7f214246a8a396aab11a3ac5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSincronizzazione tra diverse sessioni<\/p>\n<h4>Svantaggi di Golang<\/h4>\n<p>\nGolang non \u00e8 perfetto. I canali sono lenti. Rispetto alla sincronizzazione, il canale Go \u00e8 semplicemente un modo pi\u00f9 semplice di gestire eventi paralleli e in streaming, ma il canale non offre le migliori prestazioni. Sotto il canale c'\u00e8 una logica complessa di sincronizzazione. Pertanto, ho apportato alcune modifiche all'implementazione, riutilizzando le sincronizzazioni e i valori atomici per sostituire i canali al fine di ottimizzare le prestazioni.<\/p>\n<p>Inoltre, il garbage collector in Golang \u00e8 non gestito, il che provoca talvolta sospette lunghe pause. Questo ostacola notevolmente il funzionamento delle applicazioni in tempo reale.<\/p>\n<h4>CGO<\/h4>\n<p>\nIl progetto utilizza una libreria esistente VP8\/H264 open source in Golang per la compressione dei media e Libretro per gli emulatori di giochi. Tutte queste librerie sono semplicemente dei wrapper della libreria C in Go utilizzando <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/cmd\/cgo\/\">CGO<\/a><\/noindex>. Alcuni dei difetti sono elencati in <noindex><a rel=\"nofollow\" href=\"https:\/\/dave.cheney.net\/2019\/10\/06\/use-internal-packages-to-reduce-your-public-api-surface\">questo post di Dave Cheney<\/a><\/noindex>. I problemi che ho affrontato:<\/p>\n<ul>\n<li>impossibilit\u00e0 di catturare un crash in CGO, anche utilizzando Golang RecoveryCrash;<\/li>\n<li>impossibilit\u00e0 di identificare il collo di bottiglia delle performance quando non si riesce a rilevare problemi dettagliati in CGO.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Conclusione<\/h2>\n<p>\nHo raggiunto il mio obiettivo: ho compreso i servizi di gioco cloud e ho creato una piattaforma che aiuta a giocare a giochi retro nostalgici con i miei amici online. La creazione di questo progetto sarebbe stata impossibile senza la libreria Pion e il supporto della comunit\u00e0 Pion. Sono estremamente grato per il suo intenso sviluppo. Le semplici API fornite da WebRTC e Pion hanno reso l'integrazione fluida. La mia prima prova di concetto \u00e8 stata rilasciata nella stessa settimana, anche se non sapevo in anticipo della connessione peer-to-peer (P2P).<\/p>\n<p>Nonostante la semplicit\u00e0 di integrazione, lo streaming P2P \u00e8 davvero un'area molto complessa nell'informatica. Deve affrontare la complessit\u00e0 delle architetture di rete pluriennali, come IP e NAT, per creare una sessione peer-to-peer. Durante il lavoro su questo progetto ho accumulato molte conoscenze preziose su reti e ottimizzazione delle prestazioni, quindi consiglio a tutti di provare a costruire prodotti P2P utilizzando WebRTC.<\/p>\n<p>CloudRetro soddisfa tutti gli scenari d'uso che mi aspettavo, dal mio punto di vista come retro gamer. Tuttavia, penso che ci siano molte aree nel progetto che posso migliorare, come rendere la rete pi\u00f9 affidabile e performante, garantire una qualit\u00e0 grafica pi\u00f9 elevata dei giochi o la possibilit\u00e0 di condividere giochi tra gli utenti. Sto lavorando duramente per questo. Per favore, seguite <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/giongto35\/cloud-game\">progetto<\/a><\/noindex> e supportatelo se vi piace.<\/li>\n<\/ul>\n<p>Fonte: <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.1.1 - 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\/it\/blog\/administrirovanie\/oblachnyj-gejming-s-otkrytym-ishodnym-kodom-na-webrtc-p2p-multipleer-zero-latency\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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\/it\/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\udd47Gaming in cloud open source su WebRTC: p2p, multiplayer, zero latency | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/it\/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":"it_IT","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\/it\/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\/it\/wp-json\/wp\/v2\/posts\/89303","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=89303"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/89303\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/89304"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=89303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=89303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=89303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}