SlideShare a Scribd company logo
1 of 59
Download to read offline
UNIVERSITÀ DEGLI STUDI DI
TRIESTE
Dipartimento di Ingegneria e Architettura
Corso di Laurea Magistrale in Ingegneria Elettronica e
Informatica
Analisi e prototipazione di un sistema
di streaming per la localizzazione in
tempo reale
Laureando Relatore
Tibor Racman Prof. Andrea De Lorenzo
Correlatore
Ing. Alessandro Segatto
Anno Accademico 2021/2022
Indice
Introduzione iii
1 Trasmissione dei dati 1
1.1 Panoramica storica . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 Polling . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.2 Long Polling . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 WebSocket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.1 Cos’è WebSocket? . . . . . . . . . . . . . . . . . . . . . 5
1.2.2 Handshake . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 WebRTC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.1 Cos’è WebRTC? . . . . . . . . . . . . . . . . . . . . . . 8
1.3.2 ICE, STUN e TURN . . . . . . . . . . . . . . . . . . . 9
1.3.3 Signaling e SDP . . . . . . . . . . . . . . . . . . . . . . 12
1.3.4 Data Channel, SCTP e DTLS . . . . . . . . . . . . . . 13
1.3.5 Sicurezza . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.4 Confronto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.1 Stato dell’arte . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.2 Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.4.3 Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.5 WebTransport . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.5.1 Perchè QUIC? . . . . . . . . . . . . . . . . . . . . . . . 25
1.5.2 Vantaggi . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2 Visualizzazione dei dati 28
2.1 Canvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.1.1 FabricJs . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.1.2 KonvaJs . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.2 Confronto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
i
3 Implementazione prototipo 36
3.1 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.2 Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.3 Migliorie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4 Conclusioni 48
ii
Introduzione
Nell’ultimo decennio si è assistito ad una vera e propria rivoluzione dei canali
per la distribuzione dei servizi e delle opere multimediali. La migrazione
degli spettatori ai servizi di streaming, sta infliggendo perdite enormi alle
infrastrutture tradizionali come il cinema e la televisione. Il successo da
parte dei servizi di streaming è stato reso possibile grazie agli investimenti e al
perfezionamento dei metodi di trasmissione, che hanno reso la comunicazione
più robusta e fluida, migliorando di conseguenza l’esperienza visiva. Tuttavia
l’avanzare della tecnologia non si è fermato e al giorno d’oggi anche le dirette
in tempo reale, che rappresentavano l’ultimo baluardo dei servizi tradizionali,
vengono contese.
La tesi si sviluppa in un contesto simile, che seppure derivante dall’am-
bito IoT, condivide molti dei requisiti tipici delle dirette multimediali. Ci
si prefisserà in particolare lo studio dei vari protocolli di comunicazione per
la trasmissione di un flusso di dati in tempo reale e i modi più efficaci per
rappresentare questi dati, ponendo particolare attenzione sulla latenza e ro-
bustezza della trasmissione, sulla reattività e fluidità della rappresentazione
e sulle risorse del sistema utilizzate per soddisfare i requisiti precedenti. L’a-
nalisi verrà consolidata con la realizzazione di un prototipo basilare di un
sistema di streaming di localizzazione in tempo reale, che metterà in pratica
ciò che si è appreso nello studio iniziale. Per integrarsi con il sistema già
esistente in azienda, il prototipo si discosterà dalle dirette multimediali tra-
dizionali e non trasmetterà fotogrammi, ma bensı̀ dati codificati secondo gli
standard aziendali. In questo modo si coglierà anche l’occasione di esplorare
un modo alternativo per la realizzazione di una diretta streaming e di va-
lutarne i pro e i contro, sviluppando un’applicazione che non ha riferimenti
analoghi in letteratura.
Seppure il lavoro svolto non è concettualmente collegato ad un caso d’uso
in particolare, si è scelto di fissare uno scenario ben definito al fine di rendere
l’analisi e le decisioni prese sperabilmente più intuitive. Il contesto nel quale
viene sviluppata la tesi è quello di una partita di pallacanestro in diretta,
nella quale ogni giocatore verrà dotato di un sensore, che periodicamente
iii
rileverà e trasmetterà la propria posizione relativa al campo da gioco. Una
torretta a bordo campo, avrà il compito di rilevare tutte le posizioni e dopo
averle codificate in formato JSON le passerà al client. La tesi in questione si
collocherà in queste ultime fasi identificando la torretta-server con la sorgente
dei dati, che trasmetterà i dati aggiornati, ogni 30 millisecondi, rientrando
nell’intervallo dei FPS dello standard delle dirette. Il client che riceverà i
dati si occuperà di rappresentarli. Con il termine client ci si riferisce dun-
que ad una pagina web in grado di mostrare le informazioni ricevute. La
rappresentazione in questione sarà data da una vista dall’alto di un campo
da pallacanestro stilizzato, sul quale si muoveranno dei segnaposto rappre-
sentanti i giocatori. Il colore del segnaposto dipenderà dalla squadra del
giocatore. Al fine di emulare un servizio multimediale, sotto la rappresen-
tazione verranno posti dei pulsanti, con i quali lo spettatore potrà gestire il
flusso dei dati in entrata.
Il primo capitolo sarà dedicato all’analisi dei protocolli di trasmissione
dati. Il sistema prevede l’esistenza di feedback da parte dell’utente e la di-
scussione sarà quindi incentrata sui protocolli bidirezionali. Dopo una breve
panoramica storica si discuterà il protocollo più celebre in questo ambito,
il WebSocket. Si introdurrà poi un altro protocollo ha preso piede solo re-
centemente, il WebRTC. Dopo un confronto, che deciderà quale verrà usato
nel prototipo si introdurrà un terzo protocollo, il WebTransport, che è an-
cora in fase sperimentale ma che in futuro potrebbe dimostrarsi una valida
alternativa.
Nel secondo capitolo ci si occuperà invece di analizzare e confrontare i
metodi per la rappresentazione dei dati ricevuti. In particolare dopo aver in-
trodotto e discusso la nuova specifica canvas introdotta in HTML5, verranno
confrontate due delle librerie derivate più popolari.
Nel terzo capitolo verrà implementato il prototipo di trasmissione e rap-
presentazione dei dati. L’obbiettivo principale è quello di emulare un ripro-
duttore video, con riferimento particolare a quello delle dirette sulla nota
piattaforma YouTube. Oltre alla mera rappresentazione, sarà dunque neces-
sario realizzare anche un sistema di gestione del flusso, controllabile dallo
spettatore.
La parte finale è riservata per alcune considerazioni sull’implementazione
e sugli aspetti architetturali del sistema, ai suoi punti di forza e alle possi-
bili migliorie future. La tesi si concluderà con delle osservazioni su quanto
appreso durante il percorso.
iv
Capitolo 1
Trasmissione dei dati
Il capitolo si aprirà con una panoramica storica che metterà in luce le ra-
gioni che hanno portato alla nascita e allo sviluppo dei protocolli di co-
municazione bidirezionale e si focalizzerà in particolare al loro ruolo nella
trasmissione dei dati in tempo reale. Si entrerà poi in dettaglio, nel pro-
tocollo WebSocket, discutendone l’implementazione e i vantaggi che questa
soluzione apporta, rispetto ai primi metodi rudimentali, basati sulle richieste
HTTP periodiche. Successivamente verrà esplorata una nuova alternativa,
denominata WebRTC, che ha preso piede negli ultimi anni e che abbandona
il paradigma classico del client-server per abbracciarne uno più distribuito,
quello del peer-to-peer. Anche in questo caso, per poter apprezzare appieno
il protocollo, ci si addentrerà nell’implementazione, che risulterà essere più
arzigogolata essendo composta da più protocolli comunicanti tra di loro. Si
discuterà delle difficoltà tecniche di instaurazione di una connessione peer-
to-peer e sulle possibili falle di sicurezza che questo tipo di connessione può
introdurre. Tenendo in considerazione le varie osservazioni, si passerà poi ad
un breve confronto sperimentale tra i due protocolli, scegliendo in fine quello
che, relativamente ai parametri definiti a monte, si dimostrerà più idoneo ai
nostri fini. Per ultimo verrà introdotto WebTransport, che è un nuovo pro-
tocollo di comunicazione che viene implementato sopra QUIC, una variante
più performante di TCP, introdotta recentemente da Google. La trattazione
in questo caso risulterà più superficiale poiché il protocollo in questione è an-
cora in fase sperimentale, ma risulta tuttavia promettente poiché introduce
varie migliorie, che potrebbero giovare a tutte quelle applicazioni che, come
la nostra, pongono dei vincoli sulle latenze.
1
1.1 Panoramica storica
Lo schema classico della tecnologia HTTP sul quale si è sviluppata la comuni-
cazione odierna su internet vede il client ed il server rivestire ruoli altamente
asimmetrici. Nello scenario tipico infatti, il client richiede del contenuto, che
verrà poi, solo successivamente, servito dal server.
1.1.1 Polling
Con il passare del tempo e con la nascita del concetto di streaming (flusso
di dati) sono apparse le prime applicazioni web, che operavano con dati in
tempo reale. Nel tentativo di tenere il client di queste applicazioni aggiorna-
to, le richieste HTTP sono diventate, nella stessa finestra temporale, sempre
più numerose. In questo contesto si è sviluppato un modo di utilizzare il
protocollo HTTP, detto Polling, che consiste nel sollecitare periodicamente
il server, in modo da farsi dare i dati più aggiornati. Il Polling è quindi in
una serie periodica di richieste e risposte: il client richiede ad un interval-
lo prefissato, detto periodo di polling, i dati aggiornati che, se disponibili,
verranno mandati dal server.
Figura 1.1: Esempio di diagramma sequenziale del Polling. Si noti che la
seconda risposta sarà vuota non avendo intercettato l’aggiornamento e un
aggiornamento dati verrà perso
2
Data una richiesta, nel qual caso non ci siano dati nuovi, allora il server
risponderà con una risposta vuota. Ed è proprio per il numero di queste
iterazioni inutili che si vanno a creare in assenza di dati nuovi, che ha portato
alla nascita del Long Polling.
1.1.2 Long Polling
Il Long Polling è una variante del Polling, che cerca di limitare le iterazioni
client-server ridondanti, tenendo in stallo la richiesta del client fintantoché
non siano disponibili nuovi dati o fino al raggiungimento di un timer noto-
riamente più lungo del periodo di polling tradizionale. Operando in questo
modo si ricaverà la sincronizzazione implicita del client e del server e il si-
stema diventerà più flessibile in caso di cadenza di aggiornamento dati non
regolare, come mostrato in Figura [1.2] .
Figura 1.2: Esempio di diagramma sequenziale del Long Polling. Si noti
l’attesa del server dopo la seconda richiesta
Il Long Polling cerca quindi di attribuire più autonomia al server, ren-
dendolo indipendente dalle richieste del client, ma lo fa in modo fittizio,
mettendo il server in stallo fino al prossimo aggiornamento dati. Viene quin-
di simulato un push da parte del server, dato che il server può solo rispondere
al client, seppur variando i tempi di risposta. Inoltre in caso di aumento della
frequenza di aggiornamento dati, il dover sempre ripetere i headers HTTP
3
comporta un overhead di comunicazione non sostenibile. Da qui l’esigenza
di protocolli alternativi, che abbandonano completamente HTTP.
4
1.2 WebSocket
1.2.1 Cos’è WebSocket?
WebSocket è un protocollo di comunicazione, che permette di stabilire una
connessione bidirezionale, full-duplex, tra client e server, operante su una sin-
gola connessione TCP e ottimizzato per avere basse latenze di trasmissione.
Utilizza TCP come layer sottostante e ne aggiunge delle funzionalità minime:
permette al server di bloccare i client in base al loro indirizzo IP, implementa
una naming policy che permette di far girare servizi multipli su una singola
porta TCP e di avere host multipli sullo stesso indirizzo IP. Introduce inoltre,
nello stream di byte del TCP, il concetto di messaggio, utilizzando dei frame
composti da byte di controllo e da dati applicativi. Il protocollo si compone
di due parti, l’handshake iniziale, che stabilisce la connessione e lo scambio
di dati vero e proprio.
1.2.2 Handshake
L’handshake iniziale si avvale di una richiesta HTTP, come schematizzato in
Figura [1.3] ed è caratterizzato dalla presenza dello header Upgrade: websocket,
più eventuali informazioni aggiuntive atte all’instaurazione del canale di co-
municazione. Il client inizia la connessione specificando l’indirizzo del server,
seguito da un’eventuale risorsa ed il numero di porta alla quale il server è in
ascolto. Analogamente a HTTPS, si può settare un flag e richiedere l’uso di
TLS per rendere la comunicazione criptata e sicura. A differenza dei meto-
di HTTP basati sul pull, il protocollo WebSocket impone l’uso di una sola
connessione TCP per la comunicazione, in modo da minimizzare le risorse
utilizzate. Dopo aver mandato l’handshake iniziale, il client entra nello stato
di instaurazione di connessione e aspetta la risposta da parte del server.
GET /resource HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://example.com
Figura 1.3: Esempio di richiesta HTTP per l’handshake WebSocket
Il server a sua volta dopo aver ricevuto la richiesta di instaurare una
connessione WebSocket dovrà valutarne tutti i campi e solo dopo questa
5
verifica, potrà rispondere al client. Dovra assicurarsi, in particolare, che
l’indirizzo del client non sia stato esplicitamente vietato e che la versione del
protocollo ed eventuali subprotocolli o estensioni richieste dal client siano
supportati. Nel caso sia esplicitamente richiesta una connessione sicura allora
il server dovrà inanzitutto inizializzare il canale TLS. Dopo aver eseguito
la routine esposta il server risponderà al client che a sua volta validerà le
informazioni contenute nella risposta. Se tutti i requisiti sono soddisfatti
allora lo stato della connessione verrà impostato ad OPEN e sia il server, che
il client potranno iniziare a mandare dati.
Figura 1.4: Esempio di diagramma sequenziale di WebSocket. Dopo l’hand-
shake iniziale su HTTP la comunicazione diventa full-duplex
Seppure WebSocket non aggiunga molto al di sopra di TCP, il suo hand-
shake risulta quattro volte più lungo[1]. Una delle ragioni principali è data
dal fatto che una connessione TCP dovrà essere negoziata in ogni caso prima
di poter iniziare l’ handshake di WebSocket. Tuttavia dopo aver instaurato la
connessione, le performance tra WebSocket e TCP non differiscono di molto,
rendendo in pratica quasi impercettibile la differenza di livello logico. Ciò è
dato dal fatto che il protocollo è stateful e rispetto a HTTP, gli header ven-
gono ridotti all’osso spostando gran parte del controllo della comunicazione,
alla fase di negoziazione.
Il protocollo WebSocket, ha rappresentato dunque una svolta nella comu-
nicazione bidirezionale, tanto da dimostrarsi diversi ordini di grandezza più
6
performante in termini di latenze, rispetto alle precedenti tecniche basate
sul pull, soprattutto in casi di connessioni di rete non ottimali[2]. Tutta-
via con l’avvento dello streaming dal vivo, i requisiti di latenza si sono fatti
sempre più esigenti ed in presenza di perdite di dati, la reliability del proto-
collo sottostante TCP si è dimostrata un collo di bottiglia. Gli sviluppatori
quindi hanno scelto di sacrificare i dati non ricevuti in tempo, a favore dei
dati più aggiornati. Per fare ciò, è stato necessario rivedere ancora una volta
i livelli logici sottostanti, dando vita a vari protocolli basati su UDP, tra i
quali WebRTC, che negli ultimi anni si è dimostrato una valida alternativa
a WebSocket.
7
1.3 WebRTC
1.3.1 Cos’è WebRTC?
WebRTC, abbreviazione di Web Real Time Communication, è un framework
open-source creato da Google nel 2011, composto da un aggregato di pro-
tocolli, standard ed API, che messi assieme permettono a due nodi in rete,
di stabilire un servizio di comunicazione in tempo reale, come ad esempio di
messaggistica, di chiamata audio e video o di trasferimento file, senza l’au-
silio di plugin aggiuntivi. Inizialmente fu concepito per i browser ma data
la sua crescita in popolarità sono nate quasi subito librerie che ne permet-
tono l’implementazione in ambienti back-end, soprattutto quelli basati su
Javascript.
A differenza dei protocolli tradizionali, la comunicazione qui è di tipo
peer-to-peer. Con il termine peer-to-peer si indica tutti quei sistemi, nei
quali gli elementi che compongono il sistema, condividono le risorse e svolgono
contemporaneamente il ruolo di offerente e richiedente del servizio[3]. In altre
parole, le tecnologie di questo genere hanno un’architettura decentralizzata
e non prevedono l’uso di server intermediari, consentendo quindi ai client,
denominati peer, di comunicare direttamente tra di loro. Anche WebRTC
è in linea di principio serverless, anche se come si vedrà in seguito, l’uso
di server ausiliari nella fase di inizializzazione della connessione, ne facilita
l’implementazione. La API di WebRTC è composta da tre componenti:
• getUserMedia: usata per acquisire la traccia audio e video dalla camera
e dal microfono
• RTCPeerConnection: abilita la comunicazione audio e video tra i peer;
gestisce anche la sicurezza, la gestione della banda di rete e la parte di
negoziazione della comunicazione, come lo scambio delle interfaccie di
rete e dei codec multimediali utilizzati dai peer
• RTCDataChannels: usata per la comunicazione bidirezionale tra i peer
di tutti quei dati arbitrari che non fanno parte del flusso multimediale
In questa tesi l’attenzione verrà posta principalmente sulla terza componente,
che è quella che ci permetterà di trasmettere i dati relativi alle posizioni dei
giocatori sul campo da gioco.
Va notato, che WebRTC non è un protocollo nel senso stretto del termine,
bensı̀ più una serie di direttive. Questo non solo perché aggregato di più
protocolli anche facenti parte dello stesso livello logico, ma soprattutto perché
lascia ampio margine di manovra agli sviluppatori, evitando di specificare
il ‘come‘ in alcuni passi cruciali per l’implementazione di un’applicazione
8
funzionale, soprattutto in quelli relativi alla negoziazione. Nella Figura 1.5 è
schematizzata la pila dei protocolli che lo compongono, la maggior parte dei
quali verrà approfondita in seguito.
Figura 1.5: Pila dei protocolli costituenti WebRTC
1.3.2 ICE, STUN e TURN
Una delle prime difficoltà che si incontrano nella realizzazione di un sistema
peer-to-peer, come WebRTC, è quella di mettere in comunicazione i vari nodi.
Questo potrebbe non essere un problema nel caso in cui i nodi siano nella
stessa rete, ma lo diventa nello scenario tipico in cui risiedono in reti diverse.
Un nodo in rete infatti, è raggiungibile solamente all’indirizzo IP pubblico
a lui associato. Nelle architetture tradizionali questo problema non si pone,
perché i server rendono noto il proprio IP pubblico tramite il protocollo DNS.
Tuttavia in WebRTC non si hanno server e alcuni nodi potrebbero non avere
un IP pubblico dedicato ed essere quindi soggetti ad attraversamento NAT.
Il Network Address Translation è uno standard che mappa indirizzi IP di
una rete in un’altra, solitamente indirizzi IP privati in indirizzi pubblici[4],
consentendo ad un dispositivo che ne è sprovvisto, di poter navigare in re-
te. Per fare ciò si avvale di una struttura dati denominata NAT Table che
mapperà la quadrupla
(IP interno, Porta interna, IP esterno, Porta esterna)
9
in modo da poter reindirizzare le risposte derivanti dalla rete esterna, al
nodo interno che le aveva richieste. Il NAT agisce sul fronte della rete locale
ed è del tutto trasparente ai dispositivi su cui opera. Per verificare se si
trova dietro un NAT e ricavarne l’indirizzo pubblico, un nodo può avvalersi
di un server che implementa il protocollo Session Traversal Utilities for NAT.
Un server STUN, è un server che si occupa semplicemente di rispondere
con l’indirizzo IP dal quale proviene la richiesta. Hanno costi di gestione
minimi e in rete se ne trovano varie implementazioni gratuite, che permettono
l’implementazione pratica dell’ Interactive Connectivity Establishment.
Il protocollo ICE, è una tecnica usata per trovare la via ottimale per met-
tere in comunicazione diretta due peer. Si occupa di trovare tutte i fronti di
rete, detti candidati ICE, sui quali è in ascolto il nodo, interrogando l’inter-
faccia di rete del dispositivo ed eventuali sever STUN. Fatto ciò, il layer ICE
manderà, usando tecniche di signaling [1.3.3], i dati collezionati allo stesso
layer dell’interlocutore. Quest’ultimo, risponderà a sua volta con i suoi di
candidati e dopo che lo scambio è andato a buon fine, i due layer proveranno
a stabilire una connessione utilizzando i candidati ricevuti, ordinati in ordine
di latenza, provando ad esempio per primi gli indirizzi IP privati nel caso i
due peer risiedano nella stessa rete locale.
Figura 1.6: Esempio di ICE candidates gathering
Lo stabilire della connessione peer-to-peer potrebbe risultare impossibile
nel caso di alcune combinazioni di tipologie di NAT. Esistono infatti quattro
10
tipi di NAT che si differenziano per la restrittività sulle connessioni in entrata:
• Full-Cone NAT : mappa indistintamente l’IP del NAT nell’IP del Client
interno alla rete in base alla PORT in entrata
• Address Restricted NAT: lascia passare il pacchetto in entrata solo nel
caso in cui l’ IP che ha generato il pacchetto è presente nella tabella
NAT; lascia cioè passare i pacchetti in entrata solo se un qualunque
nodo interno alla rete ha mandato almeno una richiesta a quel’ IP
esterno
• Port Restricted NAT: simile al precedente ma prende in considerazione
anche la porta, ossia lascia passare i pacchetti in entrata solo se un
nodo interno ha già mandato una richiesta a quel indirizzo IP esterno
e a quella porta esterna
• Symmetric NAT: lascia passare un pacchetto in entrata solamente se la
quadrupla esiste nella tabella NAT, ovvero un pacchetto in entrata può
passare solo verso un nodo interno che lo ha richiesto precedentemente
Come sarà spiegato nella prossima sottosezione i due peer si scambiano
le informazioni per stabilire la connessione per via indiretta, utilizzando un
attore di terze parti. Nel caso di alcune combinazioni, come mostrato in
tabella 1.1 questo non è possibile perché i pacchetti che non trovano una
corrispondenza specchiata nella tabella NAT, cioè che non rappresentano una
risposta ad una richiesta generata dal nodo dietro al NAT, verranno bloccati.
In questo caso vi è la necessità di utilizzare un server che implementa il
Traversal Using Relays around NAT. Un server di questo tipo, detto server
TURN risiede all’esterno del NAT e reindirizza il traffico del peer. In questo
modo il peer manterrà una connessione solamente con il server TURN, che
gli farà da tramite nella comunicazione WebRTC.
Full-Cone Address Port Symmetric
Full-Cone STUN STUN STUN STUN
Address STUN STUN STUN STUN
Port STUN STUN STUN TURN
Symmetric STUN STUN TURN TURN
Tabella 1.1: Combinazioni che richiedono l’uso di un server TURN
I server TURN, a differenza di quelli STUN hanno costi di gestione più
significativi e le soluzioni più affidabili sono a pagamento. Inoltre l’introdu-
zione del server TURN spezza il paradigma del peer-to-peer, causando un
11
aumento di latenze notevoli nella comunicazione. La necessità di un server
TURN tra i candidati ICE di un peer per poter avere un sistema robusto
ad ogni evenienza e indipendente dalle reti locali in cui risiedono i peer,
rappresenta forse uno dei punti deboli di WebRTC.
1.3.3 Signaling e SDP
Dopo aver collezionato tutti i potenziali candidati ICE il peer che vuole ini-
ziare a comunicare deve formalizzare il proprio ‘biglietto da visita‘ usando
uno standard denominato Session Description Protocol. L’SDP è una lunga
stringa di paia key = value separati dal carattere di nuova linea n, che
oltre ai vari candidati ICE, conterrà anche informazioni relative al canale
media come i codec supportati dal peer, gli algoritmi di cifratura etc. Dopo
aver creato un offer, il peer dovrà reperirla all’interlocutore. Lo standard
WebRTC non entra nel dettaglio su come ciò debba avvenire. Tra gli svilup-
patori si è consolidata la soluzione che vede un server WebSocket dedicato,
chiamato Signaling Server, che si occuperà solo di fare da portavoce ai due
peer. Il primo peer invierà la propria offerta di disponibilità al Signaling
Server, che la inoltrerà all’altro peer. Dopo averla ricevuta, quest’ultimo ge-
nererà un answer e la manderà indietro sempre con l’ausilio del Signaling
Server. Una volta essersi scambiati le reciproche informazioni e dopo aver
trovato la via più efficiente per comunicare, i due peer potranno generare il
canale di comunicazione, il Data Channel.
Figura 1.7: Negoziazione della connessione WebRTC
12
Inizialmente lo stabilire della connessione WebRTC richiedeva più tempo,
rispetto agli altri protocolli di comunicazione. Ciò era dovuto al fatto di dover
collezionare tutti i possibili candidati ICE, prima di stabilire la connessione,
soprattutto quelli relativi ai server STUN e TURN. In alcuni casi, come ad
esempio quando i peer fanno parte della stessa rete locale, oppure in presenza
di NAT non eccessivamente restrittivi, alcuni di questi candidati risultavano
ridondanti. Per ovviare a questo problema è stato introdotto il Trickle ICE.
Il Trickle ICE è un estensione del protocollo ICE che permette di instau-
rare una connessione tra i peer, prima ancora di aver terminato la ricerca di
tutti i possibili candidati ICE. Non appena un peer avrà trovato un possibile
candidato, lo manderà all’interlocutore, con il quale proverà di instaurare
una connessione, cercando parallelamente altri possibili fronti di comunica-
zione. Nel caso un altro candidato fosse trovato, lo si manderà come possibile
fall-back di connessione, utilizzando direttamente il Data Channel se già in-
staurato oppure il signaling server. I peer dovranno in questo caso essere in
grado di differenziare i messaggi applicativi, da quelli contenenti i nuovi can-
didati. Il Trickle ICE ha diminuito i tempi di negoziazione di diversi ordini
di grandezza, sacrificando in parte la robustezza della connessione. In questo
progetto non siamo soggetti a vincoli temporali sullo stabilire la connessione
e il focus è sullo scambio dati, per questo il Trickle ICE sarà disattivato.
Un altro aspetto da notare è che per costruzione, un’offerta SDP avrà
un identificativo univoco e in condizioni normali non potrà essere riutilizzata
su più connessioni. Esistono però delle implementazioni del layer ICE che
lo permettono, fenomeno denominato ICE forking. L’ ICE forking non è
ancora implementato in WebRTC e nel nostro caso la torretta server non
potrà rendersi disponibile su più client con la stessa offerta memorizzata nel
signaling server, il che semplificherebbe la struttura del sistema.
1.3.4 Data Channel, SCTP e DTLS
I messaggi testuali tra i due interlocutori WebRTC vengono scambiati tramite
il Data Channel. A differenza dei tradizionali protocolli di comunicazione
basati su TCP, il Data Channel utilizza STCP.
Lo Stream Control Transmission Protocol è un protocollo di comunica-
zione sviluppato dal gruppo di lavoro IETF Signaling Transport ed orienta-
to alla connessione, ma che condivide molte caratteristiche con i protocolli
orientati ai messaggi [5]. Inizialmente fu pensato per le infrastrutture tele-
foniche nelle reti IP, come il VoIP, ma la sua flessibilità lo rese interessante
anche per applicazioni di natura diversa. Viene implementato sopra UDP
ma concettualmente si pone sullo stesso livello logico. A differenza dei già
noti protocolli orientati alla connessione, primo tra tutti TCP, esso offre la
13
possibilità di configurare l’affidabilità della connessione, la cosiddetta reliabi-
lity e l’ordinamento o meno della sequenza dei dati in arrivo. Risulta dunque
un ibrido che in base ai parametri di inizializzazione può avere un compor-
tamento più simile a TCP oppure più vicino a UDP. Permette inoltre di
stabilire un terzo tipo di comunicazione, detta comunicazione parzialmente
affidabile, in cui il mittente proverà a ritrasmettere un messaggio che non ha
ricevuto conferma, ma solo per un numero prefissato di volte oppure per un
certo arco di tempo, per poi passare ai messaggi seguenti [6]. Usato assieme
al protocollo ICE, supporta anche il multy-homing, ovvero la possibilità di
aggiungere più percorsi per raggiungere il nodo di destinazione. In questo
caso e se configurato in modalità affidabile, in caso di perdite, il protocollo
potrebbe provare più percorsi al fine di trovare quello che gli garantisce la
maggiore stabilità. Similmente a TCP anch’esso offre un controllo di con-
gestione, il congestion avoidance e la fast retransmit, il che si traduce in un
comportamento slow start. Tuttavia, a differenza di TCP la finestra di con-
gestione iniziale, initial congestion window (cwnd), è impostata al doppio
dell’unità massima di trasmissione, MTU e viene incrementata in base al
numero di byte confermati piuttosto che al numero di conferme in se come
avviene in TCP [7]. Le dimensioni iniziali più ampie ed il loro aumento più
aggressivo comportano delle dimensioni della finestra mediamente maggiori
e come conseguenza un throughput più elevato rispetto a TCP. Inoltre vo-
lendo la finestra iniziale può essere configurata. Quest’ultima possibilità è
stata oggetto di argomento nell’ambito WebRTC e come vedremo in seguito
può inciderne sulle prestazioni. Il controllo del flusso e quello della congestio-
ne permettono di stabilire il throughput ottimale relativo alla stabilità della
rete.
TCP UDP SCTP
Reliability Reliable Unreliable Configurable
Delivery Ordered Unordered Configurable
Transmission Stream Messages Messages
Flow Control Yes No Yes
Congestion Control Yes No Yes
Tabella 1.2: Confronto tra SCTP e i principali protocolli di comunicazione
Prima di essere passati al layer UDP, i messaggi SCTP di WebRTC, de-
vono obbligatoriamente passare attraverso il DTLS. Il Datagram Transport
Layer Security è un protocollo di comunicazione progettato per proteggere
la privacy dei dati e prevenire intercettazioni e manomissioni della trasmis-
sione da parte di malintenzionati. Si basa sulla criptazione pubblica per
14
l’autenticazione dei nodi e per la negoziazione della chiave privata, che verrà
poi utilizzata per criptare i messaggi che successivi. Tuttavia, a differen-
za dei protocolli più noti della stessa famiglia, come TLS o SSL, esso viene
implementato su UDP ed è progettato specificamente per dare supporto ai
protocolli orientati ai messaggi.
Si noti che la criptazione avviene agli estremi, endpoint, della connessio-
ne: la presenza o meno di server TURN non influisce su di essa. Quest’ultimi
infatti non avranno accesso al contenuto dei datagrammi, né potranno mani-
polarli e si limiteranno solo a reindirizzarli. A differenza del canale PeerCon-
nection, usato per scambiare dati multimediali e che usa un protocollo simile
a DTLS, ma che non cripta i header dei frame, dai quali si può estrarre delle
informazioni, il DTLS cripta tutto il payload di UDP, rendendo il Data Chan-
nel intrinsecamente più sicuro. In fine l’essere obbligatorio rende il sistema
che lo utilizza più robusto agli errori o sviste da parte degli sviluppatori.
Il supporto nativo da parte dei browser, rende WebRTC, un ottimo can-
didato per trasformare tutti quei client dedicati di applicazioni UDP in ap-
plicazioni web, indipendenti dal sistema operativo. La possibilità di stabilire
una connessione non affidabile previene inoltre problematiche di tipo head
of the line blocking, che verranno approfondite in seguito, ma che in sostan-
za vedono una mancata conferma di un pacchetto, bloccare tutto il flusso
dei messaggi. La flessibilità datagli dai protocolli sottostanti, specialmente
SCTP, permette al Data Channel di poter sacrificare l’affidabilità e l’ordina-
mento, per diminuire la latenza di trasmissione, rendendolo ideale per tutte
quelle applicazioni di streaming dal vivo, come la nostra.
1.3.5 Sicurezza
Uno dei parametri fondamentali, che viene sempre tenuto in considerazione
dagli sviluppatori quando decidono di adottare un protocollo, è il livello di
sicurezza che quest’ultimo garantisce. La natura open-source di WebRTC ci
ha permesso di valutare questo aspetto a livello di protocolli usati e nella
discussione abbiamo ipotizzato una comunicazione ideale, senza specificare
alcun threat model. Come tutti i protocolli di comunicazioni però, anche
WebRTC presenta delle possibili vulnerabilità.
La parte più critica della comunicazione WebRTC è sicuramente la ne-
goziazione. Un attaccante, che abbia controllo del signaling server potrebbe
spacciarsi per la persona con la quale si vuole dialogare. Questo scenario
apre le porte a tutta una serie di threat model, come Man in the middle, se
l’attaccante è interessato a manipolare il traffico, Reply attack se l’attaccante
vuole solo osservare la comunicazione oppure Session hijacking se l’attaccan-
te spodesta l’interlocutore e ne prende il posto. Per ovviare a tutto ciò si sta
15
cercando di stabilire una relazione biunivoca tra peer ed identità, che possa
essere verificabile da entrambe le parti. In particolare tra le soluzioni più
acclamate vi è quella dell’utilizzo di protocolli basati su delega di accesso,
come OAuth, che cede la responsabilità di autenticazione ad un servizio ester-
no detto Identity provider. Come contro a questo approccio, vi è il fatto che
entrambe le parti devono fidarsi di quel servizio, il che si traduce in pratica
nell’avere un account registrato. Un’altra possibilità promettente,che non
prevede attori di terze parti, è quella di usare un meccanismo basato su bloc-
kchain smart contract, che sono pubblici ed immutabili per natura. Questo
approccio è stato esplorato in [8], sfruttando la rete blockchain Ethereum e si
è dimostrato che la latenza introdotta dall’autenticazione che sfrutta questo
metodo risulta trascurabile.
Esistono poi, tutta una serie di vulnerabilità che sono proprie di We-
bRTC. Tra quelle che hanno suscitato più timori vi è sicuramente quella del
WebRTC Leak. La vulnerabilità colpisce soprattutto gli utenti che utilizzano
una VPN e permette all’attaccante di rivelare l’indirizzo IP pubblico delle
vittime. Questo accade in presenza di VPN configurate in modo errato, che
non dirottano il traffico STUN attraverso il tunnel VPN. Attirando le vitti-
me sul suo sito l’attaccante può quindi cercare di instaurare una connessione
WebRTC. Il browser dell’utente inizierà a sua insaputa a raccogliere tutti i
candidati ICE senza passare per la VPN, rivelando l’IP pubblico vero della
vittima. Oltre a ciò l’attaccante ricaverà anche l’indirizzo IP privato della
vittima all’interno della rete, che potrebbe essergli molto favorevole, soprat-
tutto in contesti aziendali, perché gli permetterebbe di mappare la rete e gli
faciliterebbe attacchi più mirati. Come dimostrato da Al-Fannah Nasser Mo-
hammed in [9], questo non è un problema residuale ma al contrario affligge
un ampio spettro di servizi VPN e browser.
Un’altra vulnerabilità è data dal fatto che WebRTC potrebbe indiretta-
mente facilitare l’invio di malware. Nelle piattaforme tradizionali di condi-
visione di file, che si avvalgono di un server intermedio vi è un controllo da
parte del server, dei file spediti . Nelle comunicazioni di tipo peer-to-peer
invece, questo controllo viene meno e dovrebbe essere eseguito a livello di
nodo. Questo aspetto, che il più delle volte viene trascurato [10] e unito
al fatto che l’apertura del Data Channel non viene notificata direttamente
all’utente, potrebbe permettere all’attaccante di mandare file malevoli.
Le varie vulnerabilità esposte potrebbero essere risolte in futuro, per
esempio richiedendo all’utente il permesso di rispondere ad un offerta di
comunicazione WebRTC. Tuttavia nel frattempo alcuni utenti o addirittura
produttori potrebbero decidere di disabilitare WebRTC sui propri browser
il che porterebbe alla perdita di tutta una fetta di utenti. Questo fatto de-
v’essere tenuto in considerazione nella prossima sezione che si occuperà di
16
confrontare il protocollo WebRTC con quello dei WebSocket.
17
1.4 Confronto
In questa sezione vogliamo confrontare i protocolli presentati precedente-
mente. In letteratura, si possono trovare vari studi di prestazione dei singoli
protocolli, che ci aiuteranno a stabilire gli indici che useremo per il confron-
to. Tenendo in conto i requisiti temporali da soddisfare ed il fatto di volere
sempre i dati più aggiornati, anche a fronte di perdite, potremmo decidere
quale di essi è più conforme ai nostri fini.
1.4.1 Stato dell’arte
Come visto, le prestazioni del protocollo WebSocket non differiscono di molto
rispetto a TCP e a differenza del TCP puro, Websocket ha il vantaggio di
essere applicabile direttamente nel contesto Web. Inoltre, vari studi come [1],
hanno dimostrato che, a differenza dei protocolli basati sul polling HTTP,
esso presenta meno dati ridondanti e in sessioni lunghe o in condizioni di rete
non ottimali, il traffico di rete si riduce notevolmente.
Le pubblicazioni di WebRTC invece, sono meno numerose e si focalizzano
soprattutto sulla trasmissione di contenuti multimediali, che come abbiamo
visto utilizza un altro canale. Per quanto riguarda il Data Channel, lo studio
più rilevante è sicuramente quello di Eskola e Nurminen [11], in cui si scopre
che la scelta di lasciare inalterata la dimensione iniziale della finestra SCTP,
ereditata dal protocollo originale, può influire negativamente sulla trasmis-
sione dei dati. In caso di raddoppio della latenza di rete, il throughput del
Data Channel diminuisce di un’ordine di grandezza. Tuttavia nel nostro
progetto i dati che vogliamo trasmettere hanno dimensioni massime fisse ed
il focus sarà posto sul diminuire il tempo che impiegano dalla sorgente al
consumatore. Inoltre in [12], è stato notato come WebRTC, confrontato con
altri protocolli simili, sia più dispendioso a livello di CPU il che può avere
delle ripercussioni sull’autonomia dei dispositivi mobile.
Per concludere noi valuteremo i tempi di comunicazione, gli effetti che si
hanno su di essa in presenza di degradazione della rete e l’uso delle risorse di
sistema del consumatore. Verranno tenute in considerazione anche la facilità
di implementazione e gli eventuali costi di una soluzione rispetto all’altra.
1.4.2 Setup
Per l’esperimento si è utlizzato un server locato negli Stati Uniti d’America
(Virginia) con sistema operativo Ubuntu v20.04.4 LTS e indirizzo IP pub-
blico, sul quale sono stati eseguiti due processi, uno relativo al protocollo
WebSocket e l’altro relativo a WebRTC. Per l’esecuzione è stato utilizzato
18
Node.js v16.5.0, che è un sistema a runtime, open source, multi piattaforma
orientato agli eventi, pensato per l’esecuzione di codice Javascript e costrui-
to sul motore Javascript V8 di Google Chrome. Utilizzando il gestore di
pacchetti predefinito di Node, il Node Package Manager (npm), è possibile
arricchirlo con librerie esterne. In particolare in questo esperimento sono
state utilizzate le seguenti librerie:
• ws: usata per l’implementazione del protocollo WebSocket
• simple-peer: usata per l’implementazione del protocollo WebRTC. Si
basa su node-webrtc, che fa il porting di webrtc dal mondo browser
a quello Node.js, ma ne semplifica l’utilizzo, dando la possibilità di
modificare facilmente alcuni parametri relativi alla connessione, come
ad esempio il Trickle ICE
• simple-statistics: usata per le calcolare le stime statistiche dei
tempi di latenza
Entrambe le librerie relative ai protocolli sono orientato agli eventi. In
particolare per l’esperimento che riguarda i WebSocket si ha il seguente codice
lato server:
// server.js
webSocketServer.on("connection", (webSocket) => {
console.log("New client connected");
let counter = 0;
let data = {};
const intervalID = setInterval(() => {
data = { counter: counter, timestampStart: Date.now() };
webSocket.send(JSON.stringify(data));
counter++;
if (counter > 1000) {
webSocket.close();
clearInterval(intervalID);
}
}, config.BIT_RATE);
});
che fa si che il server inizierà a mandare pacchetti al client, non appena
questo vi si connetterà. I pacchetti avranno dimensioni simili a quelli del-
l’applicazione reale e conterranno un identificativo, che sarà incrementato ad
19
ogni pacchetto e che servirà per valutare le perdite ed il timestamp dell’invio
in millisecondi, usato per stimare le latenze. Il server manderà i dati secondo
il bitrate dell’applicazione e dopo 1000 pacchetti si fermerà.
Per quanto il codice client si ha:
// client.js
webSocket.on("message", (data) => {
const msg = JSON.parse(data);
if (msg.counter > counter) {
msg.timestampEnd = Date.now();
list[counter] = msg;
}
counter = msg.counter;
});
webSocket.on("close", () => {
console.log("Closing connection from client!");
const differences = [];
for (let index = 0; index < list.length; index++) {
const e = list[index]
if (e !== undefined) {
differences[index] = e.timestampEnd - e.timestampStart;
}
}
const filteredDiff = differences
.filter((x) => x !== undefined);
const max = statistics.max(filteredDiff);
const min = statistics.min(filteredDiff);
const mean = statistics.mean(filteredDiff);
const var = statistics.variance(filteredDiff);
});
che si salverà solo i pacchetti più recenti, il che sarà utile in caso di perdite
soprattutto nel codice WebRTC, e ne memorizzerà il timestamp di arrivo.
Quando avrà ricevuto tutti i dati, valuterà i tempi di arrivo dei pacchetti
ricevuti e arrivati per tempo e ne trarrà alcune stime statistiche,.
Il codice è stato riusato in parte anche nell’esperimento con WebRTC
con la differenza che al posto della variabile webSocket, gli eventi sono stati
modellati sulla variabile che rappresenta il peer. Si ha quindi:
20
// server.js
// codice negozziazione omesso
...
const peer = new Peer({
initiator: false,
wrtc: wrtc,
config: { iceServers:
[{ urls: "stun:stun.l.google.com:19302" }] },
trickle: false,
ordered: false,
maxRetransmits: 0,
});
peer.on("connect", () => {
// codice omesso per brevità
})
dove Peer è il costruttore della variabile che modella il nodo peer-to-peer
e che prende in ingresso dei parametri relativi al ruolo, ai server STUN, al
Trickle ICE e al tipo di connessione che si vuole creare, nel nostro caso non
affidabile e non ordinata, simile ad UDP. Similmente a lato client si ha:
// client.js
// codice negozziazione omesso
...
const peer = new Peer({
initiator: true,
wrtc: wrtc,
config: { iceServers:
[{ urls: "stun:stun.l.google.com:19302" }] },
trickle: false,
ordered: false,
maxRetransmits: 0,
});
peer.on("data", () => {
// codice omesso per brevità
21
})
peer.on("close", () => {
// codice omesso per brevità
})
Per quanto riguarda la negoziazione è stato usato il protocollo WebSocket.
Il server implementa sia il signaling che l’interlocutore: dopo lo scambio
iniziale delle offerte e delle risposte tramite WebSocket si passerà a WebRTC.
L’architettura peer-to-peer viene quindi ‘adattata‘, a quella client-server, più
conforme ai nostri fini.
Inoltre, dopo aver eseguito l’esperimento, lo si è voluto ripetere in condi-
zioni di rete non ottimali. Per fare ciò, si è utilizzato Netem, un program-
ma Linux che da linea di comando permette di simulare perdite, ritardi e
corruzioni dei dati. In particolare utilizzando il comando:
sudo tc qdisc add dev wlp5s0 root netem delay 50ms loss 35%
si è aggiunto un ritardo di 50 ms e una perdita del 35 % dei pacchetti
all’interfaccia di rete wireless.
1.4.3 Risultati
L’esperimento è stato ripetuto in varie fasce orarie, per evitare distorsioni nei
dati dovute alla congestione della rete. Tuttavia l’orario si è dimostrato non
particolarmente incidente e i risultati presentati saranno presi da una delle
fasce in cui si è svolto l’esperimento.
Per quanto riguarda il protocollo WebSocket si ha per ogni pacchetto, le
seguenti differenze di tempo di arrivo e partenza, in condizioni ottimali:
0 100 200 300 400 500 600 700 800 900 1,000
0
50
100
pacchetto
latenza
(ms)
22
con un picco massimo di 47 ms ed uno minimo di 42 ms. La media è di 43.7
ms, con una varianza del 0.4 ms2
. Aumentando il ritardo di 50 ms e alzando
il numero di pacchetti persi si ha:
0 100 200 300 400 500 600 700 800 900 1,000
0
50
100
pacchetto
latenza
(ms)
con tempo di transito massimo di 129 ms, minimo di 92 ms. In media
un pacchetto transita per 102.2 ms e la varianza si aggira al 125.5 ms2
. I
picchi sono dovuti probabilmente a ritrasmissioni dei pacchetti, essendo il
protocollo affidabile ed ordinato.
Per quanto riguarda WebRTC in condizioni ottimali si ha:
0 100 200 300 400 500 600 700 800 900 1,000
0
50
100
pacchetto
latenza
(ms)
con un massimo di 44 ms, un minimo di 41 ms. In media un pacchetto
transita per 42 ms, con una varianza del 0.3 ms2
. Non si è registrata alcuna
perdita. In condizioni di rete non ottimali invece si ha:
23
0 100 200 300 400 500 600 700 800 900 1,000
0
50
100
pacchetto
latenza
(ms)
con tempo massimo 98 ms, minimo 91 ms, media del 94.5 ms e varianza
4.1 ms2
. La comunicazione è stata impostata come non affidabile e le stime
sono state calcolate senza tenere conto dei pacchetti che non hanno ricevuto
conferma o che non sono arrivati per tempo.
Nel nostro caso in condizioni di rete ottimali i protocolli risultano quasi
indistinguibili, mentre in quelle non ottimali WebRTC si dimostra legger-
mente migliore. Tuttavia anche nel caso peggiore, che è stato appositamente
esagerato, il protocollo WebSocket si è dimostrato degno, con latenze media-
mente intorno alle centinaia di millisecondi. Per quanto riguarda l’uso delle
risorse di sistema ed in particolare quello della CPU, si ha che WebRTC è
leggermente più esigente, ma risulta ancora gestibile, dato che un computer
datato di fascia media con CPU Intel i7-4700HQ 2.40 GHz ha esibito un
picco massimo di 40 % in un singolo core.
La torretta server, che farà da sorgente dati, è posizionata all’interno
dell’azienda e dietro ad un NAT di tipo simmetrico. Risulta dunque, come
spiegato in 1.3.2, necessario dotarsi di un server TURN per rendere le comu-
nicazione robusta. Considerando inoltre i risultati promettenti in entrambi
i casi, i tempi di negoziazione della connessione e che ambedue le API risul-
tano interscambiabili e non influenzano la logica dell’applicazione, abbiamo
scelto di implementare il prototipo con il protocollo WebSocket, posticipando
la scelta definitiva ad applicazione finita.
24
1.5 WebTransport
WebTransport è un protocollo di comunicazione bidirezionale nuovo, ancora
in fase sperimentale, che in futuro potrebbe spodestare WebSocket e risul-
ta quindi degno di nota. A differenza di WebRTC, esso mantiene l’impo-
stazione client-server e crea la connessione utilizzando il protocollo QUIC,
recentemente introdotto da Google.
1.5.1 Perchè QUIC?
Agli albori del Web, nel 1989, Tim Berners-Lee concepı̀ una prima bozza del
protocollo HTTP, che sarebbe stato in seguito ampiamente adottato come
sistema predefinito per la trasmissione di dati attraverso il web. Implemen-
tato sopra IP e TCP, il protocollo inizialmente era scarno e le richieste e
risposte contenevano solo il payload senza altre informazioni aggiuntive sullo
stato della connessione. Nella prima standardizzazione del HTTP 1.0 sono
state aggiunte queste informazioni sotto forma di Headers. Tuttavia questa
versione imponeva l’utilizzo di una sola connessione TCP per risorsa. Con
il crescere del Web ed ed essendo l’apertura della connessione TCP, la parte
più dispendiosa in termini di risorse, si creò rapidamente un collo di bottiglia
che venne in seguito risolto con la seconda standardizzazione. L’HTTP 1.1
permette di riutilizzare una connessione TCP e di stabilire più connessioni
TCP, solitamente sei, contemporaneamente. Tuttavia quando le connessioni
parallele sono tutte utilizzate il browser deve restare in stallo aspettando le
relative risposte. Questo fenomeno, denominato Head of Line Blocking fa
si che richieste concettualmente indipendenti, diventino dipendenti per via
della tecnologia su cui transitano. Inoltre le connessioni TCP avendo una so-
la scheda rete, sono virtuali e dato che la capacità della singola connessione
risulta maggiore del traffico nelle altre 6 si potrebbe pensare di comprimere
il tutto in un unica connessione TCP. Da questa idea è nato SPDY.
SPDY, successivamente rinominato in HTTP 2, tra le molteplici miglio-
rie, introduce il multiplexing, ossia il comprimere più traffici HTTP paralleli,
detti stream, in una sola connessione TCP. Multiple richieste HTTP, ognuna
etichettata, potranno quindi essere mandate contemporaneamente sulla stes-
sa connessione TCP. Il server dovrà differenziare i byte relativi ad ogni richie-
sta e generare le relative risposte, che a sua volta potranno essere mandate
contemporaneamente. Lo scopo del multiplexing è quindi quello di introdur-
re un certo parallelismo nelle azioni e di contrastare la mole di dati sempre
crescente, delle pagine web. L’indipendenza delle richieste però, anche in
questo caso, risulta fittizia: data la natura affidabile ed ordinata di TCP, nel
caso uno stream subisca una perdita, la ritrasmissione dei pacchetti relativi
25
bloccherebbe gli altri stream, nei quali viaggiano altre richieste indipendenti.
Il blocco Head of Line quindi, seppur è stato risolto a livello di applicazione,
permane nel layer di trasporto. Per questo motivo è stato introdotto HTTP
3, che sostituisce TCP con un nuovo protocollo meno restrittivo, denominato
QUIC.
Figura 1.8: Head of Line Blocking nelle due declinazioni: a sinistra HTTP
1.1 con il blocco delle sei connessioni TCP e a destra HTTP 2, con il blocco
dei stream nella singola connessione TCP
QUIC è un protocollo di rete a livello di trasmissione, con caratteristi-
che simili a TCP, ma implementato sopra UDP, che si prefissa il compito
di prendere il meglio dei due protocolli. Analogamente a TCP, QUIC im-
plementa un sistema di controllo di congestione, di conferma di ricezione e
ritrasmissione dati, ma lo fa a livello di stream, evitando cosı̀ il collo di botti-
glia precedentemente descritto. Oltre alla minore latenza, essendo i pacchetti
trasmessi su UDP, QUIC facilita anche l’inizializzazione della connessione.
Al giorno d’oggi infatti, per stabilire una connessione basata su TCP, biso-
gna innanzitutto portare a termine l’ handshake iniziale, per poi rendere la
connessione sicura con TLS, che a sua volta richiederà delle iterazioni. Con
QUIC la cifratura del canale è obbligatoria e viene negoziata direttamente
all’handshake, permettendo di risparmiare molteplici round trip tra il client
ed il server. Inoltre se i due hanno già interagito recentemente, QUIC può
mandare dati utili già alla richiesta di connessione. Inoltre etichettando i
pacchetti con un identificativo di connessione, permette di mantenere aperta
26
la connessione nel caso di cambio del supporto di rete da parte del disposi-
tivo. QUIC è quindi altamente versatile e configurabile e potrebbe portare
benefici non da poco, a tutti quei protocolli di comunicazione basati su TCP,
come ad esempio WebSocket. WebTransport si potrebbe riassumere come
quest’ultimo, migrato su QUIC.
1.5.2 Vantaggi
WebTransport è un protocollo di comunicazione bidirezionale costruito sopra
QUIC. Può essere configurato per comunicare con l’ausilio di datagrammi,
oppure attraverso stream di dati.
I datagrammi non garantistico nessuna garanzia sulla ricezione e sull’ordi-
ne nel quale vengono ricevuti, ma rappresentano un’ottima opzione nel caso
di applicazioni che necessitano di basse latenze. Si può pensare a questa
opzione, come al traffico UDP, ma criptato e con l’aggiunta di un controllo
di congestione.
Gli stream d’altro canto sono affidabili e ordinati ed appropriati per quelle
applicazioni che non possono scendere a compromessi in questi termini. In
questo caso il traffico sarà simile a quello TCP, ma con overhead minore e
senza problematiche di Head of Line Blocking nel caso di più stream.
A differenza di WebRTC la pila di protocolli che lo compongono è mi-
nore, il che dovrebbe rendere il protocollo più robusto e più maneggevole.
Inoltre, è supportato nativamente all’interno di Web Worker, che ne per-
mette l’esecuzione indipendentemente dalla presenza o meno di una pagina
HTML. Purtroppo al momento di scrittura di questa tesi esiste solo un pri-
mo prototipo delle WebTransport API, scritto in Go e funzionante solo sui
browser basati su Chromium, tuttavia Mozilla ha etichettato il protocollo
come Worth prototyping. Resta quindi un protocollo con molto potenziale e
degno di attenzione.
27
Capitolo 2
Visualizzazione dei dati
In questo capitolo si esplorerà i metodi migliori per rappresentare i dati ri-
cevuti, mediante l’elemento canvas introdotto nelle specifiche di HTML 5.
Dopo un’infarinatura della tecnologia Canvas e dei suoi pregi e difetti ri-
spetto ad altre soluzioni per il disegno web, si discuterà la possibilità di
usare librerie derivate da essa, che semplificano le API native. In particolare
verranno discusse e confrontate due delle librerie canvas specializzate nella
grafica bidimensionale più popolari, FabricJs e KonvaJs. Le specifiche, se-
condo le quelli verranno messe alla prova le due librerie verranno ricavate dai
requisiti relativi al front-end di reattività e fluidità della rappresentazione,
misurando i tempi di inizializzazione della pagina e visualizzazione dei dati
ricevuti.
28
2.1 Canvas
Canvas è un elemento dello standard HTML5 che permette il rendering dina-
mico di immagini bitmap attraverso Javascript. Fu introdotto inizialmente
da Apple per uso all’interno del loro componente proprietario WebKit, ai
fini di migliorare il browser Safari, ma data la sua versatilità fu presto adot-
tato anche dagli altri browser e standardizzato dal WHATWG nelle nuove
specifiche proposte per le tecnologie della prossima generazione.
Il Canvas consiste in una regione disegnabile, le cui dimensioni vengono
specificate dagli attributi height and width. Il codice Javascript può ac-
cedere all’area con un set completo di funzioni, permettendo la generazione
dinamica di disegni. Come struttura sottostante viene utilizzata una semplice
bitmap, memorizzata nel browser, sulla quale verrà disegnato, richiamando i
comandi di disegno nativi del sistema operativo. Più specificamente quando
il browser farà il parsing di un documento HTML contenente un elemento
<canvas>, dovrà allocare sullo schermo una mappa di pixel, che coprirà l’a-
rea specificata. Per fare ciò può agire in modo autonomo, per esempio con
una chiamata malloc(), oppure si può avvalere delle API di grafica, nati-
ve del sistema operativo, come ad esempio DirectX, Gtk, Kde Plasma, Qt
etc. Dopo che la superficie di disegno è stata creata, viene resa accessibile
all’interprete Javascript attraverso un puntatore. Quando l’interprete Java-
script vedrà l’invocazione di un metodo canvas, lo delegherà al browser, che
lo passerà a sua volta al sistema operativo sottostante. Il dialogo tra il brow-
ser ed il sistema operativo è trasparente allo sviluppatore che per disegnare,
impiegherà solamente codice Javascript .
A differenza delle precedenti tecnologie per la grafica web, come il plug-
in Flash, Canvas non richiede alcuna estensione aggiuntiva ed è ampiamente
supportato da tutti i browser. Il plug-in Flash infatti, veniva integrato come
oggetto embedded esterno e non poteva comunicare con gli altri elementi della
pagina, mentre Canvas, essendo integrato nello standard HTML5 e parte
integrante del DOM, può interagire con esso. Questo estende le possibili
animazioni e l’iterazione con l’utente e rende il caricamento della pagina più
veloce e di conseguenza la navigazione più fluida.
Un’altra tecnologia per la grafica web, simile al Canvas e che è stata an-
ch’essa introdotta recentemente nello standard HTML5 è quella del SVG. La
Scalable Vector Graphics, è un particolare tipo di grafica, che si pone l’obbiet-
tivo di descrivere figure bidimensionali. A differenza del Canvas, che viene
rappresentato nel DOM come un singolo elemento, una tela, l’SVG lavora in
XML e ogni oggetto diviene un elemento del DOM a se stante. Questo si
traduce in due modi diversi di disegno: Canvas disegnerà in immediate mode,
mentre SVG in retained mode.
29
Il modo immediato è pixel oriented ossia, il meccanismo di disegno non
tiene traccia delle forme disegnate e il browser disegnerà semplicemente i pixel
della tela. Se vi sono due oggetti sovrapposti si preoccuperà semplicemente
di disegnare quello sovrapposto e non vi sarà traccia di quello sottostante.
Questo porta a delle prestazioni più elevate, soprattutto nel caso in cui bi-
sogna ridisegnare più oggetti [13], ma delega allo sviluppatore il compito di
tenere eventualmente conto delle forme e dare dunque un significato logico
al disegno.
Il modo memorizzato invece risulta essere shape oriented, ovvero per ogni
forma il browser allocherà una porzione di memoria che verrà singolarmente
passata al API grafica, per creare una bitmap corrispondente. L’appesanti-
re la memoria relativa al DOM e la molteplicità delle chiamate API, rende
l’SVG mediamente meno performante, rispetto al Canvas, ma in compenso
si ha nativamente il controllo su ogni singolo elemento disegnato. Fortu-
natamente esistono librerie canvas che implementano questo controllo sugli
oggetti disegnati, senza però sacrificare drammaticamente le prestazioni del
Canvas.
2.1.1 FabricJs
FabricJs è una libreria canvas, che punta a semplificare le API Canvas native
e uniformarle al paradigma della programmazione ad oggetti. A differen-
za di quest’ultime infatti, che operano sul contesto (ossia un oggetto che
rappresenta tutta la tela bitmap), FabricJs opera sui singoli oggetti disegna-
ti, permettendoci di stabilire una corrispondenza di ereditarietà tra di essi.
FabricJs si occuperà inoltre della gestione di memoria del canvas e del rende-
ring degli oggetti. Questo viene ottenuto trasparentemente, instanziando più
canvas e formando cosı̀ degli strati, in modo da poter tenere fisso un livello,
come ad esempio lo sfondo, variando contemporaneamente i livelli superiori,
che permette di implementare un sistema di caching e risparmiare risorse
di computazione, soprattutto nel caso delle animazioni, ottenute variando
le proprietà degli oggetti nei vari frame renderizzati sequenzialmente. Con
una sintassi che rassomiglia le librerie Javascript per la manipolazione del
DOM come ad esempio jQuery, è possibile associare ad ogni oggetto un certo
comportamento in risposta ad un evento ben definito. FabricJs è disponibile
anche a lato server, il che lo rende un ottimo candidato per la variazione
implementativa che verrà discussa nelle Conclusioni [4].
FabricJs si aggancerà ad un elemento di tipo <canvas>, definito nel file
html di base. Quando la pagina verrà caricata si inizializzerà la tela, che
raffigurerà nel nostro caso, il campo da gioco. In particolare verrà richiamata
la funzione:
30
function init() {
const canvas = new fabric.Canvas("canvas", config.canvas);
const circles = Array(config.players)
.fill({})
.map(() => new fabric.Circle(config.circle));
fabric.Image.fromURL(config.urlImage, (img) => {
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas),
{
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height,
backgroundImageStretch: false,
hoverCursor: "pointer",
backgroundColor: null,
});
});
circles.forEach((circle, index) => {
if (index >= 5) {
circle.fill = "blue";
}
circle.top = initialPositions.players.at(index).top;
circle.left = initialPositions.players.at(index).left;
canvas.add(circle);
});
}
La funzione disegnerà la tela ed un segnaposto, in questo caso cerchi, per
ogni giocatore. Un’immagine del campo da gioco, la cui risoluzione verrà
ridimensionata a quella del canvas verrà posta come sfondo e ogni giocatore
riceverà una colorazione in base alla squadra appartenente e verrà posto nella
posizione iniziale ricoperta dal suo ruolo. Dopo aver invocato la funzione la
tela si presenterà come in Figura 2.1
Alternativamente, il canvas potrebbe essere inizializzato usando l’oggetto
StaticCanvas. Questa variante non dà la possibilità all’utente di interagire
con il canvas in futuro, ma alleggerisce il carico computazionale. In que-
sto modo ogni miglioria basata sull’iterazione, come ad esempio il mostrare
le informazioni di un certo giocatore cliccando sopra al relativo segnapo-
sto, verrebbe troncata, ma in compenso il sistema potrebbe dimostrarsi più
reattivo. Nel confronto con la prossima libreria verrà presa in considerazio-
31
ne l’implementazione che si dimostrerà migliore secondo gli indici definiti in
seguito.
Figura 2.1: Canvas inizializzato
Ad ogni messaggio contenente le posizioni aggiornate, si disegnerà un
nuovo frame:
function drawOnCanvas(newPositions) {
circles.forEach((circle, index) => {
circle.top = newPositions.at(index).top;
circle.left = newPositions.at(index).left;
}
canvas.renderAll();
}
Data l’alta frequenza di aggiornamento non verrà richiesta alcuna anima-
zione tra un frame e l’altro.
2.1.2 KonvaJs
KonvaJs è un’altra libreria Canvas popolare, specializzata anch’essa nella
grafica bidimensionale. L’elemento che farà da ancora nel file html princi-
pale in questo caso sarà un <div> sul quale verrà instanziato uno Stage.
32
Ogni Stage conterrà a sua volta uno o più Layer, sui quali verranno dise-
gnate le varie forme. I layer sono implementati con l’ausilio di due elementi
<canvas>, il primo che ha il compito di renderizzare la scene, mentre il
secondo è ottimizzato per rilevare gli eventi relativi alle forme sulla tela.
A differenza di FabricJs quindi KonvaJs offre allo sviluppatore una granu-
larità di configurazione più fine. Nel nostro caso la funzione di inizializzazione
si traduce in:
function init() {
const stage = new Konva.Stage(config.canvas);
const layer = new Konva.Layer();
const background = new Konva.Layer();
stage.add(background);
stage.add(layer);
const circles = Array(config.players)
.fill({})
.map(() => new Konva.Circle(config.circle));
Konva.Image.fromURL(config.urlImage, (img) => {
img.setAttrs({
scaleX: stage.width() / img.width(),
scaleY: stage.height() / img.height(),
});
background.add(img);
background.draw();
});
circles.forEach((circle, index) => {
if (index >= 5) {
circle.fill("blue");
}
circle.position(initialPositions[index]);
layer.add(circle);
});
layer.draw();
}
che produrrà lo stesso risultato ottenuto anche in precedenza e visibile in
33
Figura 2.1. Analogamente a prima, alla ricezione delle nuove posizioni seguirà
l’aggiornamento della tela:
function drawOnCanvas(newPositions) {
circles.forEach((circle, index) => {
circle.position({
x: newPositions.at(index).x,
y: newPositions.at(index).y
});
}
layer.draw();
}
34
2.2 Confronto
Il confronto FabricJs e KonvaJs è stato effettuato con l’ausilio del tool di
misurazione di prestazioni di Chrome, registrando i tempi di tutti i passi
relativi alla ricezione e alla visualizzazione dei dati durante una diretta dal
vivo. Dalle misurazioni delle prestazioni, in un finestra temporale di 5 minuti,
si sono ricavati i seguenti risultati:
Idle
Scripting
Rendering
Painting
System
90.12%
3.39%
2.11%
2.07%
2.31%
89.03%
4.14%
2.16%
2.32%
2.34% KonvaJs
FabricJs
Figura 2.2: Suddivisione delle fasi per la visualizzazione dei dati
Come si può notare dal diagramma in Figura [2.2], il sistema a front-end
passa la maggior parte del tempo in stallo. I tempi di renderizzazione e di-
segno dei dati risultano infinitesimi in ambedue i casi ed entrambe le librerie
sono quindi soddisfacenti. Le prestazioni sono quasi del tutto coincidenti, il
che sta ad indicare che entrambe le librerie al di sotto utilizzano , le stes-
se API Canvas HTML5 e che le tecniche di caching, nelle quali potrebbero
differenziarsi, non sono influenti per le dimensioni dei dati in questione. Te-
nendo in considerazione la qualità della documentazione in rete e la facilità
di sviluppo, si è scelto di utilizzare FabricJs.
35
Capitolo 3
Implementazione prototipo
L’obbiettivo principale di questo capitolo è quello di mettere in pratica quan-
to appreso fin’ora emulando un riproduttore dello streaming, prendendo come
punto di riferimento il riproduttore live della nota piattaforma di YouTube.
La rappresentazione verrà realizzata utilizzando FabricJs e WebSocket, le due
tecnologie scelte precedentemente. Inizialmente verrà illustrata l’interfaccia
per poi addentrarsi nella realizzazione. Oltre alla mera rappresentazione dei
dati infatti, bisognerà realizzare anche un sistema di gestione del flusso, con-
trollabile dallo spettatore. A tal scopo verrà introdotta una nuovo tipo di
architettura del software, quella guidata ad eventi, che permetterà di risolve-
re i problemi di concorrenzialità e scalabilità. In fine verranno discussi alcuni
accorgimenti e migliorie che potrebbero rendere il sistema più robusto, indi-
pendente dai protocolli sottostanti e giovare quindi all’esperienza utente in
generale.
36
3.1 Client
Per implementazione del player si intende la codifica da parte del client, dei
comandi che controllano il flusso di dati e l’atteggiamento che deve assumere
il server dopo aver ricevuto tali comandi. Si discuterà ora la prima e in
seguito la seconda.
A livello client si hanno due file principali: index.html, che determina la
struttura del documento e index.js, che ne implementa la logica di funzio-
namento ed il file config.js, che per comodità ragrupperà tutti i parametri
di configurazione. Il file HTML oltre ad importare i vari fogli di stile come
Bootstrap e gli script relativi alla libreria canvas che verrà utilizzata, defini-
sce anche i quattro pulsanti che verranno utilizzati per gestire il flusso e che
verranno posti sotto la tela canvas che animerà le posizioni. Questi sono rela-
tivamente: il pulsante play che ordinerà al server di mandare i dati a partire
da una certo frame temporale, il pulsante range che servirà a scegliere questo
frame e che verrà aggiornato ad ogni ricezione di dati, il pulsante pause che
fermerà la ricezione ordinando al server di mettersi in stallo ed il pulsante
live, che farà si che il client riceva i dati più aggiornati indipendentemente
dal frame corrente.
Figura 3.1: Comandi player per la gestione del flusso
Lo script principale, si occuperà di definire il funzionamento di questi
pulsanti, le relazioni tra di essi e di gestire i dati in entrata. Dopo aver definito
i riferimenti al pulsanti si occuperà di aprire la connessione bidirezionale, in
questo caso WebSocket, con il server. La connessione avrà delle direttive, in
particolare:
const ws = new WebSocket(‘ws://localhost:${config.PORT}‘);
if (ws) {
ws.onopen = () => {
playButton.disabled = false;
liveButton.disabled = false;
pauseButton.disabled = true;
rangeButton.value = 0;
};
37
ws.onmessage = (message) => {
message = JSON.parse(message.data);
updateRange(message.frame, message.max);
drawOnCanvas(message.positions);
};
}
A connessione instaurata porterà il frame di riferimento a zero e abiliterà
i pulsanti per far partire lo streaming. Quando riceverà un messaggio si
occuperà di aggiornare la barra del range e la posizione del puntatore e di
disegnare i giocatori sul campo secondo le posizioni ricevute. I pulsanti, una
volta cliccati, manderanno alla torretta server degli ordini e si disabiliteranno:
playButton.onclick = () => {
ws.send(JSON.stringify({ frame: rangeButton.value, type: "play" }));
playButton.disabled = true;
liveButton.disabled = false;
pauseButton.disabled = false;
};
liveButton.onclick = () => {
ws.send(JSON.stringify({ type: "live" }));
playButton.disabled = true;
liveButton.disabled = true;
pauseButton.disabled = false;
};
pauseButton.onclick = () => {
ws.send(JSON.stringify({ frame: rangeButton.value, type: "pause" }));
pauseButton.disabled = true;
playButton.disabled = false;
liveButton.disabled = false;
liveButton.style.color = "";
};
rangeButton.oninput = (e) => {
liveButton.style.color =
e.target.value === rangeButton.max ? "red" : "";
liveButton.disabled = e.target.value === rangeButton.max;
};
38
rangeButton.onchange = (e) => {
ws.send(
JSON.stringify({
frame: e.target.value,
type: "jump",
live: e.target.value === rangeButton.max,
})
);
};
Il pulsante di range reagirà inoltre ogni qualvolta la posizione del range
subirà un cambiamento, ovvero se ci sarà un input. In questo caso controllerà
se si è a fine corsa del range e in questo caso colorerà il pulsante live in
rosso e lo disabiliterà, stando a indicare che si sta seguendo lo streaming in
diretta. Nel qual caso fosse l’utente a cambiare frame, allora oltre all’input
verrà innescato anche l’evento change, che si attiverà quando lo slider verrà
rilasciato e che notificherà al server di riavvolgere lo streaming dal frame
indicato oppure se il frame è l’ultimo, di mandare i dati più aggiornati.
Figura 3.2: Comandi player durante la visione in diretta
Di default gli eventi relativi al pulsante di range, sia l’input che il change,
non vengono innescati quando il puntatore del range viene modificato per
via programmatica, ma solo quando viene fatto esplicitamente dall’utente.
function updateRange(value, max) {
rangeButton.max = max;
rangeButton.value = value;
rangeButton.dispatchEvent(new Event("input"));
}
Per ovviare a questo problema, durante l’aggiornamento della barra di
scorrimento, viene innescato manualmente l’evento di input, simulando il
cambio da parte dell’utente. Lo stesso paradigma degli eventi verrà usato,
anche se per motivi diversi, nella parte server.
39
3.2 Server
Il server deve ricevere i dati aggiornati, memorizzarli ed eventualmente fornire
all’utente i dati richiesti. Concettualmente questo corrisponde a due cicli:
uno che segue i risvolti della partita e che è indipendente dal fatto che un
utente sia connesso o meno e un altro che manda i dati ad eventuali utenti
connessi. Idealmente si vorrebbe un certo ordine sincronizzato tra i due,
ossia ad ogni aggiornamento seguirebbe il mandare dei dati. Definendo due
cicli indipendenti, anche se con lo stesso clock, il sincronismo non sarebbe
garantito e lo sfasamento tra i cicli sarebbe aggravato dalle tempistiche dei
comandi da parte dell’utente. Bisogna quindi comprimere il tutto ad un
unico ciclo. Inizialmente si potrebbe pensare di condensare il tutto nel ciclo
principale di aggiornamento e valutare l’invio di dati con un costrutto di tipo
if-else sulla una variabile rappresentante la connessione. Tuttavia in questo
modo la variabile in questione potrebbe rappresentare un’unica connessione,
poiché non sarebbe possibile mappare la diramazione nel flusso principale e
più client potrebbero influenzare a vicenda il proprio flusso di dati. Occorre
allora seguire una struttura denominata Event-Driven Architecture.
Figura 3.3: A sinistra un’architettura tradizionale, a destra un’architettura
di tipo Event-Driven
Un’architettura guidata ad eventi è un architettura software ed un mo-
dello di design per applicazioni, concepito per evitare fenomeni di collisione
40
tra i componenti applicativi e ridurre la complessità di sincronizzazione. A
differenza dei tradizionali modelli richiesta-risposta, la comunicazione tra i
vari attori, realizzata attraverso gli eventi, è parte integrante del sistema.
Nel nostro caso, come schematizzato in Figura [3.3] al posto di cercare di
orchestrare con un puntatore le ramificazioni, date dagli utenti connessi, dal
flusso principale, si delega la responsabilità alle ramificazioni stesse. Ad ogni
ciclo di aggiornamento dati nel flusso principale verrà innescata una notifica
di update, che si dilagherà ad ogni connessione esistente. La singola connes-
sione riceverà, a connessione instaurata, le direttive su come comportarsi in
caso di ricezione della notifica update. Nel caso di assenza di spettatori, le
notifiche resteranno vacanti, mentre se esiste una connessione, essa deciderà
in modo indipendente dal ciclo principale, se inviare i dati o meno, a secon-
da degli ordini impartiti precedentemente dall’utente. In termini di codice
questo si traduce in:
setInterval(() => {
getNewPositions();
eventEmitter.emit("update");
}, config.BIT_RATE);
...
dal flusso principale, mentre per le ramificazioni si ha:
...
const wss = new WebSocketServer({ port: config.PORT });
console.log(‘Server is running on port ${config.PORT}‘);
wss.on("connection", (ws) => {
console.log("New client has connected");
ws.state = "pause";
eventEmitter.on("update", () => {
switch (ws.state) {
case "live":
data = JSON.stringify({
frame: userFrame,
positions: history[userFrame],
max: history.length - 1,
});
ws.send(data);
userFrame = history.length;
41
break;
case "play":
data = JSON.stringify({
frame: userFrame,
positions: history[userFrame],
max: history.length - 1,
ws.send(data);
userFrame++;
break;
case "pause":
break;
}
});
...
dove ws.state è lo stato della connessione, impostato dall’utente tramite
i controlli descritti precedentemente, mentre history rappresenta la strut-
tura dati che memorizza le posizioni relative ai frame precedenti. In una
release definitiva, questa struttura dati potrebbe essere data da un’istanza
di database. Lo studio delle prestazioni di un database esula dallo scopo
di questa tesi e sebbene la scrittura e la lettura dei dati hanno tempisti-
che diverse, si può ipotizzare che questi tempi siano trascurabili rispetto al
config.BIT_RATE, che assume un valore che si aggira sulla trentina di mil-
lisecondi. Nel prototipo quindi è stato usato un semplice array, che viene
incrementato ad ogni chiamata di getNewPositions(). In questo caso an-
che la diretta verrà visualizzata mostrando i dati, che sono stati memorizzati
per ultimi.
Lo userFrame rappresenta il frame corrente e coincide, a livello client, con
il puntatore sulla barra di riproduzione. Viene incrementato ad ogni invio di
dati, assicurandosi inoltre, se siamo in diretta, che coincida con la lunghezza
dell’array memorizzato e che al prossimo ciclo prenderà gli ultimi dati. Se
si è in pausa il contatore viene congelato e i dati non vengono spediti. In
questo caso la barra di riproduzione rimarrà obsoleta per tutto il tempo che il
flusso è in pausa perché non riceverà i dati sul frame massimo. Riprendendo
il flusso dopo una pausa si avrà un riassestamento del range della barra e di
conseguenza della posizione relativa al range del puntatore. Per ovviare a ciò
bisognerebbe continuare ad aggiornare il massimo anche quando si è in pausa
ma ciò corrisponderebbe visivamente ad un puntatore che scorre all’indietro.
Si è notato che anche le dirette su YouTube hanno lo stesso problema di
42
riassestamento dopo una pausa e analogamente ad esse si è scelto di seguire
la prima strada, essendo il sistema pensato soprattutto per la diretta con al
più pause di breve durata.
Come visto precedentemente lo spettatore gestisce il flusso con i pulsanti
di controllo che a livello di server modificano lo stato della visione e impostano
in caso il frame da cui far partire la riproduzione:
...
ws.on("message", (msg) => {
msg = JSON.parse(msg);
switch (msg.type) {
case "live":
ws.state = "live";
userFrame = history.length - 1;
break;
case "play":
ws.state = "play";
userFrame = msg.frame;
break;
case "jump":
userFrame = msg.frame;
if (ws.state !== "pause") {
if (msg.live) {
ws.state = "live";
} else {
ws.state = "play";
}
}
break;
case "pause":
ws.state = "pause";
userFrame = msg.frame;
break;
}
});
tra i quali quello più articolato risulta essere il comando di salto, modifica
del puntatore nella barra di riproduzione. Se il sistema non è in pausa infatti
43
bisognerà verificare se il puntatore è stato trascinato alla fine della barra, il
che si traduce nella richiesta di una diretta o di una normale riproduzione
negli altri casi.
La riproduzione dei dati, sia di quelli precedenti, che di quelli correnti sarà
ricevuta dal client, che si occuperà di rappresentarla attraverso tecnologia
canvas.
44
3.3 Migliorie
Ogni sistema di trasmissione e visualizzazione dati, soprattutto in ambito
multimediale, implementa degli accorgimenti a front-end, che rendono più
fluida l’esperienza visiva e mitigano i danni causati dai possibili ritardi e per-
dite di dati. La tecnica più diffusa per fare ciò, è quella del buffering, che
consiste nell’introdurre una struttura dati, denominata buffer, che conterrà
alcuni campioni passati e futuri rispetto ai dati visualizzati. L’utente potrà
in questo modo variare localmente la riproduzione, senza dover interagire con
il server e se la cadenza di ricezione dei dati è maggiore rispetto a quella di
visualizzazione, allora il sistema avrà modo di stabilizzare la connessione in
caso di turbolenze di comunicazione, senza che l’utente se ne accorga. Nel
nostro caso è possibile introdurre due stati del sistema ed un semplice ar-
ray di lunghezza pari: se il sistema è nello stato play, allora l’array verrà
riempito con metà campioni passati e metà futuri, mentre se è nello stato
live si riempirà l’array con soli campioni passati. Tuttavia nel nostro caso
la visualizzazione dei dati segue immediatamente la ricezione e non si avreb-
bero tutti i benefici di stabilità descritti precedentemente se non quello di
risparmiare sulle iterazioni con il server. Si può tuttavia emulare il compor-
tamento del buffering in condizioni di rete non ottimali, dal punto di vista
dello spettatore, per rendere il sistema più robusto.
Figura 3.4: Schermata di caricamento dei nuovi dati
45
Il nostro sistema infatti, cosı̀ com’è stato concepito, non prevede dati
non ordinati oppure perdite dei dati da parte del sistema di comunicazioni
e non permette quindi, di sostituire il protocollo sottostante del WebSocket,
con uno più permissivo in termini di affidabilità, come quello del WebRTC.
Banalmente, con perdite di dati si avrebbe un riproduzione a singhiozzo,
mentre con dati non ordinati una riproduzione caotica. Per far fronte a
ciò si potrebbe pensare di introdurre la schermata di caricamento in Figura
[3.4], comunemente nota come schermata di buffering, che segnali all’utente
la scarsità delle risorse di rete e che duri fino alla ricezione dei nuovi dati.
Il funzionamento di base sarà simile a quello del timer di acknowledgemnt
del TCP: quando il front-end riceverà un messaggio da parte della torretta
server, allora reinizializzerà il contatore, se esistente, rimuoverà la schermata
di caricamento, se presente. Se un dato non verrà ricevuto in tempo, il
contatore raggiungerà il fine corsa e mostrerà la schermata di caricamento.
La lunghezza del contatore dovrà quindi essere configurata in modo adeguato
per dare tempo ai dati di raggiungere il front-end. Nel caso di cadenza di
ricezione dei dati regolare, non si avranno interruzioni, tuttavia non appena
uno o più dati tarderanno ad arrivare l’utente ne verrà a conoscenza. La
schermata di caricamento verrà implementata da due funzioni:
function buffering(time) {
clearTimeout(timer);
canvas.remove(icon);
blur(false);
timer = setTimeout(() => {
blur(true);
fabric.Image.fromURL(config.urlBufferingIcon, (img) => {
img.scale(0.2);
img.originX = "center";
img.originY = "center";
canvas.add(img);
canvas.centerObject(img);
icon = img;
setInterval(
() =>
img.animate("angle", "+=20", {
duration: 50,
onChange: canvas.renderAll.bind(canvas)
}),
50
46
);
});
}, time);
}
la funzione base si occuperà di implementare la logica di base e gestire
l’animazione di rotazione dell’icona di caricamento centrale che nel nostro
caso è una circonferenza tagliata, mentre la funzione di sfocatura si occuperà
di applicare i relativi filtri al canvas:
function blur(active) {
canvas.backgroundImage.filters.pop();
const filter = active
? new fabric.Image.filters.Blur({blur: 0.1}) : null;
canvas.backgroundImage.filters.push(filter);
canvas.backgroundImage.applyFilters();
canvas.getObjects().forEach((object) => {
object.visible = !active;
});
}
Con l’introduzione della schermata di caricamento, si è risolto il problema
della mancata ricezione dei dati ma resta il problema dell’ordinamento. Per
rendere il font-end indipendente da ciò, si potrebbe pensare di visualizzare un
dato, solo se l’identificativo numerico del dato è maggiore o uguale al valore
del puntatore del range della barra di riproduzione. Dato che quest’ultimo
è sincronizzato con i dati del server, allora i dati passati, non espressamente
richiesti dall’utente, non verrebbero visualizzati.
Facendo partire il timer alla visualizzazione e combinando quindi la scher-
mata di caricamento, con il vincolo di visualizzazione dei dati, si rende il
sistema indipendente dal protocollo di trasmissione sottostante.
47
Capitolo 4
Conclusioni
L’obbiettivo dell’analisi e della prototipazione del sistema di streaming in
diretta è stato raggiunto. Restano tuttavia da fare alcune considerazioni
finali sull’implementazione, la struttura dell’applicazione e sulle cose apprese
da questa tesi.
Come si è visto nel confronto della sezione 1.4 non vi è una sostanziale
differenza tra la latenza che si ottiene utilizzando WebRTC e quella che si ha
con WebSocket. Cio è è da attribuirsi alle dimensioni dei dati transitanti del-
l’applicazione. Tuttavia utilizzando le API di WebSocket si ha la possibilità
di differenziare la risorsa rappresentante la diretta di una partita, direttamen-
te con l’URL senza doverlo fare per via programmatica. Utilizzando inoltre
un framework di applicazioni web che integra la gestione WebSocket, come
ad esempio express-ws, si potrebbe estendere elegantemente l’applicazione
ad un sito web, che ospita più incontri in diretta, ognuno con il proprio player
incapsulato come componente.
Dato che, come osservato nella sezione 2.2, il carico di visualizzazione dei
dati sul canvas risulta minimo e che le risorse utilizzate per eseguire questa
operazione sono trascurabili, si potrebbe pensare di spostare il tutto a lato
server. Le librerie come FabricJS sono infatti supportate nativamente nel-
l’ambiente NodeJs e i fotogrammi del campo da gioco verrebbero scattati
direttamente dal server, per poi essere spediti al client. In questa ottica, la
scelta di WebRTC risulterebbe più sensata dato che verrebbe utilizzato il ca-
nale dedicato e ottimizzato per la trasmissione di flussi multimediali, mentre
il canale dei dati arbitrari si potrebbe utilizzare per la gestione del flusso da
parte del client, oppure per creare una bacheca di commenti condivisa dagli
spettatori, similmente a come accade nelle dirette di Youtube. Mandando
inoltre i dati con un flusso multimediale, non si avrebbe la necessità, a livello
di client, di creare a mano il player, dato che si potrebbe utilizzare diretta-
48
mente l’elemento <video> introdotto da HTML5, oppure librerie Javascript
più raffinate come Video.Js. Utilizzare pezzi di codice già consolidati dalla
comunità dovrebbe sperabilmente portare a meno bug e di norma dovrebbe
essere la corsia preferenziale.
Durante lo svolgimento della tesi ho avuto modo di imbattermi in pro-
tocolli di comunicazione e tecnologie lato frontend a me prima sconosciuti.
Analizzando l’implementazione dei primi ho preso dimestichezza con le do-
cumentazioni RFC e ho avuto modo di imbattermi in concetti nuovi, relativi
alle reti di calcolatori, come ad esempio il peer-to-peer e di ampliare quelli
appresi precedentemente durante la mia carriera universitaria, come il NAT.
A lato frontend ho avuto modo di prendere dimestichezza con gli strumenti
di sviluppo del browser e di implementare un’ architettura guidata ad eventi.
Ho consolidato inoltre la mia conoscenza del linguaggio Javascript, in parti-
colare ES6, anche per la gestione della parte backend, con l’ausilio di NodeJs,
integrato con librerie aggiuntive. In definitiva mi considero soddisfatto dello
svolgimento della tesi.
49
Bibliografia
[1] D. Skvorc, M. Horvat, and S. Srbljic. Performance evaluation of web-
socket protocol for implementation of full-duplex web streams. IEEE
Internet Computing, pages 1003—-1008, May 2014.
[2] Victoria Pimentel and Bradford G. Nickerson. Communicating and
displaying real-time data with websocket. IEEE Internet Computing,
16(4):45–53, May 2012.
[3] G. Camarillo. Peer-to-peer (p2p) architecture: Definition, taxonomies,
examples, and applicability. RFC 5694, RFC Editor, November 2009.
https://www.rfc-editor.org/rfc/rfc5694.
[4] Pyda Srisuresh and Matt Holdrege. Ip network address translator (nat)
terminology and considerations. RFC 2663, RFC Editor, August 1999.
http://www.rfc-editor.org/rfc/rfc2663.
[5] R. Stewart. Stream control transmission protocol. RFC 4960, RFC
Editor, September 2007. http://www.rfc-editor.org/rfc/rfc4960.
[6] Jim Fisher. How does reliability work in data
channel? https://jameshfisher.com/2017/01/17/
webrtc-datachannel-reliability/.
[7] Oracle Documentation. Stream control transfer protocol over-
view. docs.oracle.com/en/industries/communications/
enterprise-session-border-controller/8.3.0/configuration/
stream-control-transfer-protocol-overview.html.
[8] Berat Yilmaz, Ertugrul Barak, and Suat Ozdemir. Improving webrtc
security via blockchain based smart contracts. IEEE, December 2020.
[9] Al-Fannah Nasser Mohammed. One leak will sink a ship: Webrtc ip
address leaks. In 2017 International Carnahan Conference on Security
Technology (ICCST), pages 1–5, 2017.
50
[10] Ben Feher, Lior Sidi, Asaf Shabtai, Rami Puzis, and Leonardas Maro-
zas. Webrtc security measures and weaknesses. International Journal of
Internet Technology and Secured Transactions, 8(1):78–102, May 2018.
[11] Rasmus Eskola and Jukka K Nurminen. Performance evaluation of we-
brtc data channels. In Symposium on Computers and Communication,
pages 676–680. IEEE Computer Society Conference Publishing Services,
2015.
[12] Arto Heikkinen, Timo Koskela, and Mika Ylianttila. Performance eva-
luation of distributed data delivery on mobile devices using webrtc.
In 2015 International Wireless Communications and Mobile Computing
Conference (IWCMC), pages 1036–1042, 2015.
[13] Boris Smus. Performance of canvas versus svg. https://smus.com/
canvas-vs-svg-performance/ (2009/01/19).
[14] Hector Stenger. Utilizing webrtc datachannels in a server-to-peer
connection. Master’s thesis, University of Amsterdam, 2018.
[15] Dan Ristic. Learning WebRTC. Packt Publishing, 2015.
[16] Andreas Reiter and Alexander Marsalek. Webrtc: Your privacy is at
risk. In Proceedings of the Symposium on Applied Computing, pages
664–669. Association of Computing Machinery, 2017.
[17] I. Fette and A. Melnikov. The websocket protocol. RFC 6455, RFC
Editor, December 2011. https://www.rfc-editor.org/rfc/rfc6455.
[18] R. Jesup, S. Loreto, and M. Tüxen. Webrtc data channels. RFC
8831, RFC Editor, January 2021. https://www.rfc-editor.org/rfc/
rfc8831.
[19] M. Petit-Huguenin, G. Salgueiro, J. Rosenberg, D. Wing, R. Mahy, and
P. Matthews. Session traversal utilities for nat (stun). RFC 8489, RFC
Editor, February 2020. http://www.rfc-editor.org/rfc/rfc8489.
[20] J. Rosenberg. Interactive connectivity establishment (ice): A protocol
for network address translator (nat) traversal for offer/answer protocols.
RFC 5245, RFC Editor, April 2010. http://www.rfc-editor.org/
rfc/rfc5245.
[21] H. Alvestrand. Transports for webrtc. RFC 8835, RFC Editor, January
2021. http://www.rfc-editor.org/rfc/rfc8835.
51
[22] C. Holmberg, S. Hakansson, and G. Eriksson. Web real-time communi-
cation use cases and requirements. RFC 7478, RFC Editor, March 2015.
http://www.rfc-editor.org/rfc/rfc7478.
[23] Henrik Boström Cullen Jennings and Jan-Ivar Bruaroey. Webrtc 1.0:
Real-time communication between browsers. https://www.w3.org/TR/
webrtc/ (2020/10/20).
[24] NTT Communications. A study of webrtc security. https://
webrtc-security.github.io/.
[25] Tim Steeves. Webrtc nat traversal methods: A case
for embedded turn. https://www.liveswitch.io/blog/
webrtc-nat-traversal-methods-a-case-for-embedded-turn(2022/03/13).
[26] Peter Thatcher. Multi-device calls with ice forking. https://signal.
org/blog/ice-forking/ (2021/01/26).
[27] E. Ivov, J. Uberti, and P. Saint-Andre. Trickle ice: Incremental
provisioning of candidates for the interactive connectivity establish-
ment (ice) protocol. RFC 8838, RFC Editor, January 2021. http:
//www.rfc-editor.org/rfc/rfc8838.
[28] Michael Welzl. Network Congestion Control: Managing Internet Traffic.
John Wiley & Sons, 2005.
[29] MDN Contributors. Evolution of http. https://developer.
mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_
of_HTTP(2022/05/13).
[30] Alessandro Ghedini. The road to quic. https://blog.cloudflare.
com/the-road-to-quic/(2018/07/28).
[31] Jeff Posnick. Using webtransport. https://web.dev/
webtransport/(2022/01/22).
[32] RedHat Blog. What is event-driven architectu-
re? https://www.redhat.com/en/topics/integration/
what-is-event-driven-architecture (2019/09/27).
[33] Robert Lane. Event-driven programming in node.js.
https://www.digitalocean.com/community/tutorials/
nodejs-event-driven-programming (2018/01/11).
52
[34] Josh Marinacci. Html canvas deep dive. https://joshondesign.com/
p/books/canvasdeepdive/title.html.
[35] Fabricjs. https://fabricjs.com.
[36] Konvajs. https://konvajs.org.
53

More Related Content

What's hot

Msc Dissertation Fibre Composite Adaptive Systems
Msc Dissertation Fibre Composite Adaptive SystemsMsc Dissertation Fibre Composite Adaptive Systems
Msc Dissertation Fibre Composite Adaptive Systemsmaria_mingallon
 
Photonic computing
Photonic computingPhotonic computing
Photonic computingArslan Ali
 
Antennas: A Collection
Antennas: A CollectionAntennas: A Collection
Antennas: A Collection3G4G
 
Optical communications
Optical communicationsOptical communications
Optical communicationskrishslide
 
Silicon Photonics for HPC Interconnects
Silicon Photonics for HPC InterconnectsSilicon Photonics for HPC Interconnects
Silicon Photonics for HPC Interconnectsinside-BigData.com
 
Ch 1 optical fiber introduction
Ch 1 optical fiber introductionCh 1 optical fiber introduction
Ch 1 optical fiber introductionkpphelu
 
Open Access Network: Infrastructure sharing
Open Access Network: Infrastructure sharingOpen Access Network: Infrastructure sharing
Open Access Network: Infrastructure sharingHedi Hmida (PhD)
 
Free Space Optics
Free  Space  OpticsFree  Space  Optics
Free Space OpticsBise Mond
 
Implementing HLS server with GO
Implementing HLS server with GOImplementing HLS server with GO
Implementing HLS server with GOSangwon Lee
 
Photonics and Mobile Communications
Photonics and Mobile CommunicationsPhotonics and Mobile Communications
Photonics and Mobile CommunicationsAbhinav Somani
 
Channel models for fso
Channel models for fsoChannel models for fso
Channel models for fsoFalak Shah
 
NTN channel model relative work.pptx
NTN channel model relative work.pptxNTN channel model relative work.pptx
NTN channel model relative work.pptxssuser60a6ab1
 
Rms705 b 1-manuel_technique_fr
Rms705 b 1-manuel_technique_frRms705 b 1-manuel_technique_fr
Rms705 b 1-manuel_technique_fre-genieclimatique
 
Sky X Tech PPT by Manoj Datt
Sky X Tech PPT by Manoj DattSky X Tech PPT by Manoj Datt
Sky X Tech PPT by Manoj DattManoj Datt
 
An Elementary Introduction to Intermetallics in Ball Bonds
An Elementary Introduction to Intermetallics in Ball BondsAn Elementary Introduction to Intermetallics in Ball Bonds
An Elementary Introduction to Intermetallics in Ball BondsChristopher Breach
 
تعريف مبسط للالياف البصرية وأهمية السلامة عند استخدامها
 تعريف مبسط للالياف البصرية وأهمية السلامة عند استخدامها تعريف مبسط للالياف البصرية وأهمية السلامة عند استخدامها
تعريف مبسط للالياف البصرية وأهمية السلامة عند استخدامهاssghemati
 
Connectors coupler-fdf
Connectors coupler-fdfConnectors coupler-fdf
Connectors coupler-fdfBala V
 

What's hot (20)

Network Slicing overview_v6
Network Slicing overview_v6Network Slicing overview_v6
Network Slicing overview_v6
 
Msc Dissertation Fibre Composite Adaptive Systems
Msc Dissertation Fibre Composite Adaptive SystemsMsc Dissertation Fibre Composite Adaptive Systems
Msc Dissertation Fibre Composite Adaptive Systems
 
Photonic computing
Photonic computingPhotonic computing
Photonic computing
 
Antennas: A Collection
Antennas: A CollectionAntennas: A Collection
Antennas: A Collection
 
Optical communications
Optical communicationsOptical communications
Optical communications
 
Silicon Photonics for HPC Interconnects
Silicon Photonics for HPC InterconnectsSilicon Photonics for HPC Interconnects
Silicon Photonics for HPC Interconnects
 
SLX Camera General 031114 (Ukr)
SLX Camera General 031114 (Ukr)SLX Camera General 031114 (Ukr)
SLX Camera General 031114 (Ukr)
 
Ch 1 optical fiber introduction
Ch 1 optical fiber introductionCh 1 optical fiber introduction
Ch 1 optical fiber introduction
 
Open Access Network: Infrastructure sharing
Open Access Network: Infrastructure sharingOpen Access Network: Infrastructure sharing
Open Access Network: Infrastructure sharing
 
Free Space Optics
Free  Space  OpticsFree  Space  Optics
Free Space Optics
 
Implementing HLS server with GO
Implementing HLS server with GOImplementing HLS server with GO
Implementing HLS server with GO
 
Photonics and Mobile Communications
Photonics and Mobile CommunicationsPhotonics and Mobile Communications
Photonics and Mobile Communications
 
Channel models for fso
Channel models for fsoChannel models for fso
Channel models for fso
 
NTN channel model relative work.pptx
NTN channel model relative work.pptxNTN channel model relative work.pptx
NTN channel model relative work.pptx
 
Rms705 b 1-manuel_technique_fr
Rms705 b 1-manuel_technique_frRms705 b 1-manuel_technique_fr
Rms705 b 1-manuel_technique_fr
 
Sky X Tech PPT by Manoj Datt
Sky X Tech PPT by Manoj DattSky X Tech PPT by Manoj Datt
Sky X Tech PPT by Manoj Datt
 
An Elementary Introduction to Intermetallics in Ball Bonds
An Elementary Introduction to Intermetallics in Ball BondsAn Elementary Introduction to Intermetallics in Ball Bonds
An Elementary Introduction to Intermetallics in Ball Bonds
 
تعريف مبسط للالياف البصرية وأهمية السلامة عند استخدامها
 تعريف مبسط للالياف البصرية وأهمية السلامة عند استخدامها تعريف مبسط للالياف البصرية وأهمية السلامة عند استخدامها
تعريف مبسط للالياف البصرية وأهمية السلامة عند استخدامها
 
Connectors coupler-fdf
Connectors coupler-fdfConnectors coupler-fdf
Connectors coupler-fdf
 
Abaqus
AbaqusAbaqus
Abaqus
 

Similar to Analisi e prototipazione di un sistema di streaming per la localizzazione in tempo reale.pdf

Caratterizzazione dei sistemi cloud per la Pubblica Amministrazione
Caratterizzazione dei sistemi cloud per la Pubblica AmministrazioneCaratterizzazione dei sistemi cloud per la Pubblica Amministrazione
Caratterizzazione dei sistemi cloud per la Pubblica AmministrazioneAmmLibera AL
 
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...Luca Bressan
 
Application_level_SLA_monitoring
Application_level_SLA_monitoringApplication_level_SLA_monitoring
Application_level_SLA_monitoringNicola Mezzetti
 
Progetto, realizzazione e caratterizzazione dell'elettronica di acquisizione ...
Progetto, realizzazione e caratterizzazione dell'elettronica di acquisizione ...Progetto, realizzazione e caratterizzazione dell'elettronica di acquisizione ...
Progetto, realizzazione e caratterizzazione dell'elettronica di acquisizione ...MarcoCautero1
 
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...danieledegan
 
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...Paolo Morandini
 
Digitalizzazione di un processo industriale
Digitalizzazione di un processo industrialeDigitalizzazione di un processo industriale
Digitalizzazione di un processo industrialeGiulioDeBiasio2
 
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...Filippo Muscolino
 
Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business Andrea Cavicchini
 
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...Francesco Cucari
 
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Davide Bravin
 
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...michael_mozzon
 
Il modello di Cloud della PA
Il modello di Cloud della PAIl modello di Cloud della PA
Il modello di Cloud della PAMassimo Talia
 
Progetto e realizzazione di uno strumento per la raccolta di dipendenze archi...
Progetto e realizzazione di uno strumento per la raccolta di dipendenze archi...Progetto e realizzazione di uno strumento per la raccolta di dipendenze archi...
Progetto e realizzazione di uno strumento per la raccolta di dipendenze archi...LorenzoFabbio
 
a1dddf507ce838f51f5349d2b2c25241
a1dddf507ce838f51f5349d2b2c25241a1dddf507ce838f51f5349d2b2c25241
a1dddf507ce838f51f5349d2b2c25241Nunzio Meli
 
Integrazione e sviluppo di una piattaforma per la gestione delle conformità a...
Integrazione e sviluppo di una piattaforma per la gestione delle conformità a...Integrazione e sviluppo di una piattaforma per la gestione delle conformità a...
Integrazione e sviluppo di una piattaforma per la gestione delle conformità a...Alessandro Umek
 
Anomaly detection in network traffic flows with big data analysis techniques
Anomaly detection in network traffic flows with big data analysis techniques Anomaly detection in network traffic flows with big data analysis techniques
Anomaly detection in network traffic flows with big data analysis techniques Maurizio Cacace
 
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...Ce.Se.N.A. Security
 

Similar to Analisi e prototipazione di un sistema di streaming per la localizzazione in tempo reale.pdf (20)

Caratterizzazione dei sistemi cloud per la Pubblica Amministrazione
Caratterizzazione dei sistemi cloud per la Pubblica AmministrazioneCaratterizzazione dei sistemi cloud per la Pubblica Amministrazione
Caratterizzazione dei sistemi cloud per la Pubblica Amministrazione
 
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
Estrazione automatica di informazioni da documenti cartacei: progetto e reali...
 
Application_level_SLA_monitoring
Application_level_SLA_monitoringApplication_level_SLA_monitoring
Application_level_SLA_monitoring
 
Progetto, realizzazione e caratterizzazione dell'elettronica di acquisizione ...
Progetto, realizzazione e caratterizzazione dell'elettronica di acquisizione ...Progetto, realizzazione e caratterizzazione dell'elettronica di acquisizione ...
Progetto, realizzazione e caratterizzazione dell'elettronica di acquisizione ...
 
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
Autenticazione Continua Durante la Navigazione Web Basata sulla Dinamica del ...
 
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
Tesi: Progetto e realizzazione di un sistema robusto di gestione dei dati per...
 
Digitalizzazione di un processo industriale
Digitalizzazione di un processo industrialeDigitalizzazione di un processo industriale
Digitalizzazione di un processo industriale
 
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
Analisi e sviluppo di un sistema collaborativo simultaneo per la modifica di ...
 
Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business Cloud Computing e Modelli di Business
Cloud Computing e Modelli di Business
 
Tesi_Adamou
Tesi_AdamouTesi_Adamou
Tesi_Adamou
 
Tesi_Adamou
Tesi_AdamouTesi_Adamou
Tesi_Adamou
 
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
Art Everywhere: progetto per workshop Google. Sviluppo di sistemi di pattern ...
 
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
Analisi e realizzazione di uno strumento per la verifica di conformità su sis...
 
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
Implementazione di protocolli e simulatori MATLAB per lo sviluppo del livello...
 
Il modello di Cloud della PA
Il modello di Cloud della PAIl modello di Cloud della PA
Il modello di Cloud della PA
 
Progetto e realizzazione di uno strumento per la raccolta di dipendenze archi...
Progetto e realizzazione di uno strumento per la raccolta di dipendenze archi...Progetto e realizzazione di uno strumento per la raccolta di dipendenze archi...
Progetto e realizzazione di uno strumento per la raccolta di dipendenze archi...
 
a1dddf507ce838f51f5349d2b2c25241
a1dddf507ce838f51f5349d2b2c25241a1dddf507ce838f51f5349d2b2c25241
a1dddf507ce838f51f5349d2b2c25241
 
Integrazione e sviluppo di una piattaforma per la gestione delle conformità a...
Integrazione e sviluppo di una piattaforma per la gestione delle conformità a...Integrazione e sviluppo di una piattaforma per la gestione delle conformità a...
Integrazione e sviluppo di una piattaforma per la gestione delle conformità a...
 
Anomaly detection in network traffic flows with big data analysis techniques
Anomaly detection in network traffic flows with big data analysis techniques Anomaly detection in network traffic flows with big data analysis techniques
Anomaly detection in network traffic flows with big data analysis techniques
 
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
Rilevamento di attacchi di rete tramite protocolli di monitoraggio per router...
 

Recently uploaded

Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DISCIPIO Antonio
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DISCIPIO AntonioGiornata Tecnica da Piave Servizi, 11 aprile 2024 | DISCIPIO Antonio
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DISCIPIO AntonioServizi a rete
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ROMANO' Davide
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ROMANO' DavideGiornata Tecnica da Piave Servizi, 11 aprile 2024 | ROMANO' Davide
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ROMANO' DavideServizi a rete
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ALBIERO Andrea
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ALBIERO AndreaGiornata Tecnica da Piave Servizi, 11 aprile 2024 | ALBIERO Andrea
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ALBIERO AndreaServizi a rete
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DI DOMENICO Simone
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DI DOMENICO SimoneGiornata Tecnica da Piave Servizi, 11 aprile 2024 | DI DOMENICO Simone
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DI DOMENICO SimoneServizi a rete
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | SERRA Giorgio
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | SERRA GiorgioGiornata Tecnica da Piave Servizi, 11 aprile 2024 | SERRA Giorgio
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | SERRA GiorgioServizi a rete
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | RENZI Daniele
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | RENZI DanieleGiornata Tecnica da Piave Servizi, 11 aprile 2024 | RENZI Daniele
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | RENZI DanieleServizi a rete
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | CADEI Giovanni
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | CADEI GiovanniGiornata Tecnica da Piave Servizi, 11 aprile 2024 | CADEI Giovanni
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | CADEI GiovanniServizi a rete
 

Recently uploaded (7)

Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DISCIPIO Antonio
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DISCIPIO AntonioGiornata Tecnica da Piave Servizi, 11 aprile 2024 | DISCIPIO Antonio
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DISCIPIO Antonio
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ROMANO' Davide
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ROMANO' DavideGiornata Tecnica da Piave Servizi, 11 aprile 2024 | ROMANO' Davide
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ROMANO' Davide
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ALBIERO Andrea
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ALBIERO AndreaGiornata Tecnica da Piave Servizi, 11 aprile 2024 | ALBIERO Andrea
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | ALBIERO Andrea
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DI DOMENICO Simone
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DI DOMENICO SimoneGiornata Tecnica da Piave Servizi, 11 aprile 2024 | DI DOMENICO Simone
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | DI DOMENICO Simone
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | SERRA Giorgio
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | SERRA GiorgioGiornata Tecnica da Piave Servizi, 11 aprile 2024 | SERRA Giorgio
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | SERRA Giorgio
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | RENZI Daniele
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | RENZI DanieleGiornata Tecnica da Piave Servizi, 11 aprile 2024 | RENZI Daniele
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | RENZI Daniele
 
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | CADEI Giovanni
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | CADEI GiovanniGiornata Tecnica da Piave Servizi, 11 aprile 2024 | CADEI Giovanni
Giornata Tecnica da Piave Servizi, 11 aprile 2024 | CADEI Giovanni
 

Analisi e prototipazione di un sistema di streaming per la localizzazione in tempo reale.pdf

  • 1. UNIVERSITÀ DEGLI STUDI DI TRIESTE Dipartimento di Ingegneria e Architettura Corso di Laurea Magistrale in Ingegneria Elettronica e Informatica Analisi e prototipazione di un sistema di streaming per la localizzazione in tempo reale Laureando Relatore Tibor Racman Prof. Andrea De Lorenzo Correlatore Ing. Alessandro Segatto Anno Accademico 2021/2022
  • 2.
  • 3. Indice Introduzione iii 1 Trasmissione dei dati 1 1.1 Panoramica storica . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1.1 Polling . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1.2 Long Polling . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 WebSocket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.1 Cos’è WebSocket? . . . . . . . . . . . . . . . . . . . . . 5 1.2.2 Handshake . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.3 WebRTC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.3.1 Cos’è WebRTC? . . . . . . . . . . . . . . . . . . . . . . 8 1.3.2 ICE, STUN e TURN . . . . . . . . . . . . . . . . . . . 9 1.3.3 Signaling e SDP . . . . . . . . . . . . . . . . . . . . . . 12 1.3.4 Data Channel, SCTP e DTLS . . . . . . . . . . . . . . 13 1.3.5 Sicurezza . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.4 Confronto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.4.1 Stato dell’arte . . . . . . . . . . . . . . . . . . . . . . . 18 1.4.2 Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.4.3 Risultati . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.5 WebTransport . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 1.5.1 Perchè QUIC? . . . . . . . . . . . . . . . . . . . . . . . 25 1.5.2 Vantaggi . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2 Visualizzazione dei dati 28 2.1 Canvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 2.1.1 FabricJs . . . . . . . . . . . . . . . . . . . . . . . . . . 30 2.1.2 KonvaJs . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.2 Confronto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 i
  • 4. 3 Implementazione prototipo 36 3.1 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 3.2 Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3.3 Migliorie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 4 Conclusioni 48 ii
  • 5. Introduzione Nell’ultimo decennio si è assistito ad una vera e propria rivoluzione dei canali per la distribuzione dei servizi e delle opere multimediali. La migrazione degli spettatori ai servizi di streaming, sta infliggendo perdite enormi alle infrastrutture tradizionali come il cinema e la televisione. Il successo da parte dei servizi di streaming è stato reso possibile grazie agli investimenti e al perfezionamento dei metodi di trasmissione, che hanno reso la comunicazione più robusta e fluida, migliorando di conseguenza l’esperienza visiva. Tuttavia l’avanzare della tecnologia non si è fermato e al giorno d’oggi anche le dirette in tempo reale, che rappresentavano l’ultimo baluardo dei servizi tradizionali, vengono contese. La tesi si sviluppa in un contesto simile, che seppure derivante dall’am- bito IoT, condivide molti dei requisiti tipici delle dirette multimediali. Ci si prefisserà in particolare lo studio dei vari protocolli di comunicazione per la trasmissione di un flusso di dati in tempo reale e i modi più efficaci per rappresentare questi dati, ponendo particolare attenzione sulla latenza e ro- bustezza della trasmissione, sulla reattività e fluidità della rappresentazione e sulle risorse del sistema utilizzate per soddisfare i requisiti precedenti. L’a- nalisi verrà consolidata con la realizzazione di un prototipo basilare di un sistema di streaming di localizzazione in tempo reale, che metterà in pratica ciò che si è appreso nello studio iniziale. Per integrarsi con il sistema già esistente in azienda, il prototipo si discosterà dalle dirette multimediali tra- dizionali e non trasmetterà fotogrammi, ma bensı̀ dati codificati secondo gli standard aziendali. In questo modo si coglierà anche l’occasione di esplorare un modo alternativo per la realizzazione di una diretta streaming e di va- lutarne i pro e i contro, sviluppando un’applicazione che non ha riferimenti analoghi in letteratura. Seppure il lavoro svolto non è concettualmente collegato ad un caso d’uso in particolare, si è scelto di fissare uno scenario ben definito al fine di rendere l’analisi e le decisioni prese sperabilmente più intuitive. Il contesto nel quale viene sviluppata la tesi è quello di una partita di pallacanestro in diretta, nella quale ogni giocatore verrà dotato di un sensore, che periodicamente iii
  • 6. rileverà e trasmetterà la propria posizione relativa al campo da gioco. Una torretta a bordo campo, avrà il compito di rilevare tutte le posizioni e dopo averle codificate in formato JSON le passerà al client. La tesi in questione si collocherà in queste ultime fasi identificando la torretta-server con la sorgente dei dati, che trasmetterà i dati aggiornati, ogni 30 millisecondi, rientrando nell’intervallo dei FPS dello standard delle dirette. Il client che riceverà i dati si occuperà di rappresentarli. Con il termine client ci si riferisce dun- que ad una pagina web in grado di mostrare le informazioni ricevute. La rappresentazione in questione sarà data da una vista dall’alto di un campo da pallacanestro stilizzato, sul quale si muoveranno dei segnaposto rappre- sentanti i giocatori. Il colore del segnaposto dipenderà dalla squadra del giocatore. Al fine di emulare un servizio multimediale, sotto la rappresen- tazione verranno posti dei pulsanti, con i quali lo spettatore potrà gestire il flusso dei dati in entrata. Il primo capitolo sarà dedicato all’analisi dei protocolli di trasmissione dati. Il sistema prevede l’esistenza di feedback da parte dell’utente e la di- scussione sarà quindi incentrata sui protocolli bidirezionali. Dopo una breve panoramica storica si discuterà il protocollo più celebre in questo ambito, il WebSocket. Si introdurrà poi un altro protocollo ha preso piede solo re- centemente, il WebRTC. Dopo un confronto, che deciderà quale verrà usato nel prototipo si introdurrà un terzo protocollo, il WebTransport, che è an- cora in fase sperimentale ma che in futuro potrebbe dimostrarsi una valida alternativa. Nel secondo capitolo ci si occuperà invece di analizzare e confrontare i metodi per la rappresentazione dei dati ricevuti. In particolare dopo aver in- trodotto e discusso la nuova specifica canvas introdotta in HTML5, verranno confrontate due delle librerie derivate più popolari. Nel terzo capitolo verrà implementato il prototipo di trasmissione e rap- presentazione dei dati. L’obbiettivo principale è quello di emulare un ripro- duttore video, con riferimento particolare a quello delle dirette sulla nota piattaforma YouTube. Oltre alla mera rappresentazione, sarà dunque neces- sario realizzare anche un sistema di gestione del flusso, controllabile dallo spettatore. La parte finale è riservata per alcune considerazioni sull’implementazione e sugli aspetti architetturali del sistema, ai suoi punti di forza e alle possi- bili migliorie future. La tesi si concluderà con delle osservazioni su quanto appreso durante il percorso. iv
  • 7. Capitolo 1 Trasmissione dei dati Il capitolo si aprirà con una panoramica storica che metterà in luce le ra- gioni che hanno portato alla nascita e allo sviluppo dei protocolli di co- municazione bidirezionale e si focalizzerà in particolare al loro ruolo nella trasmissione dei dati in tempo reale. Si entrerà poi in dettaglio, nel pro- tocollo WebSocket, discutendone l’implementazione e i vantaggi che questa soluzione apporta, rispetto ai primi metodi rudimentali, basati sulle richieste HTTP periodiche. Successivamente verrà esplorata una nuova alternativa, denominata WebRTC, che ha preso piede negli ultimi anni e che abbandona il paradigma classico del client-server per abbracciarne uno più distribuito, quello del peer-to-peer. Anche in questo caso, per poter apprezzare appieno il protocollo, ci si addentrerà nell’implementazione, che risulterà essere più arzigogolata essendo composta da più protocolli comunicanti tra di loro. Si discuterà delle difficoltà tecniche di instaurazione di una connessione peer- to-peer e sulle possibili falle di sicurezza che questo tipo di connessione può introdurre. Tenendo in considerazione le varie osservazioni, si passerà poi ad un breve confronto sperimentale tra i due protocolli, scegliendo in fine quello che, relativamente ai parametri definiti a monte, si dimostrerà più idoneo ai nostri fini. Per ultimo verrà introdotto WebTransport, che è un nuovo pro- tocollo di comunicazione che viene implementato sopra QUIC, una variante più performante di TCP, introdotta recentemente da Google. La trattazione in questo caso risulterà più superficiale poiché il protocollo in questione è an- cora in fase sperimentale, ma risulta tuttavia promettente poiché introduce varie migliorie, che potrebbero giovare a tutte quelle applicazioni che, come la nostra, pongono dei vincoli sulle latenze. 1
  • 8. 1.1 Panoramica storica Lo schema classico della tecnologia HTTP sul quale si è sviluppata la comuni- cazione odierna su internet vede il client ed il server rivestire ruoli altamente asimmetrici. Nello scenario tipico infatti, il client richiede del contenuto, che verrà poi, solo successivamente, servito dal server. 1.1.1 Polling Con il passare del tempo e con la nascita del concetto di streaming (flusso di dati) sono apparse le prime applicazioni web, che operavano con dati in tempo reale. Nel tentativo di tenere il client di queste applicazioni aggiorna- to, le richieste HTTP sono diventate, nella stessa finestra temporale, sempre più numerose. In questo contesto si è sviluppato un modo di utilizzare il protocollo HTTP, detto Polling, che consiste nel sollecitare periodicamente il server, in modo da farsi dare i dati più aggiornati. Il Polling è quindi in una serie periodica di richieste e risposte: il client richiede ad un interval- lo prefissato, detto periodo di polling, i dati aggiornati che, se disponibili, verranno mandati dal server. Figura 1.1: Esempio di diagramma sequenziale del Polling. Si noti che la seconda risposta sarà vuota non avendo intercettato l’aggiornamento e un aggiornamento dati verrà perso 2
  • 9. Data una richiesta, nel qual caso non ci siano dati nuovi, allora il server risponderà con una risposta vuota. Ed è proprio per il numero di queste iterazioni inutili che si vanno a creare in assenza di dati nuovi, che ha portato alla nascita del Long Polling. 1.1.2 Long Polling Il Long Polling è una variante del Polling, che cerca di limitare le iterazioni client-server ridondanti, tenendo in stallo la richiesta del client fintantoché non siano disponibili nuovi dati o fino al raggiungimento di un timer noto- riamente più lungo del periodo di polling tradizionale. Operando in questo modo si ricaverà la sincronizzazione implicita del client e del server e il si- stema diventerà più flessibile in caso di cadenza di aggiornamento dati non regolare, come mostrato in Figura [1.2] . Figura 1.2: Esempio di diagramma sequenziale del Long Polling. Si noti l’attesa del server dopo la seconda richiesta Il Long Polling cerca quindi di attribuire più autonomia al server, ren- dendolo indipendente dalle richieste del client, ma lo fa in modo fittizio, mettendo il server in stallo fino al prossimo aggiornamento dati. Viene quin- di simulato un push da parte del server, dato che il server può solo rispondere al client, seppur variando i tempi di risposta. Inoltre in caso di aumento della frequenza di aggiornamento dati, il dover sempre ripetere i headers HTTP 3
  • 10. comporta un overhead di comunicazione non sostenibile. Da qui l’esigenza di protocolli alternativi, che abbandonano completamente HTTP. 4
  • 11. 1.2 WebSocket 1.2.1 Cos’è WebSocket? WebSocket è un protocollo di comunicazione, che permette di stabilire una connessione bidirezionale, full-duplex, tra client e server, operante su una sin- gola connessione TCP e ottimizzato per avere basse latenze di trasmissione. Utilizza TCP come layer sottostante e ne aggiunge delle funzionalità minime: permette al server di bloccare i client in base al loro indirizzo IP, implementa una naming policy che permette di far girare servizi multipli su una singola porta TCP e di avere host multipli sullo stesso indirizzo IP. Introduce inoltre, nello stream di byte del TCP, il concetto di messaggio, utilizzando dei frame composti da byte di controllo e da dati applicativi. Il protocollo si compone di due parti, l’handshake iniziale, che stabilisce la connessione e lo scambio di dati vero e proprio. 1.2.2 Handshake L’handshake iniziale si avvale di una richiesta HTTP, come schematizzato in Figura [1.3] ed è caratterizzato dalla presenza dello header Upgrade: websocket, più eventuali informazioni aggiuntive atte all’instaurazione del canale di co- municazione. Il client inizia la connessione specificando l’indirizzo del server, seguito da un’eventuale risorsa ed il numero di porta alla quale il server è in ascolto. Analogamente a HTTPS, si può settare un flag e richiedere l’uso di TLS per rendere la comunicazione criptata e sicura. A differenza dei meto- di HTTP basati sul pull, il protocollo WebSocket impone l’uso di una sola connessione TCP per la comunicazione, in modo da minimizzare le risorse utilizzate. Dopo aver mandato l’handshake iniziale, il client entra nello stato di instaurazione di connessione e aspetta la risposta da parte del server. GET /resource HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Protocol: chat Sec-WebSocket-Version: 13 Origin: http://example.com Figura 1.3: Esempio di richiesta HTTP per l’handshake WebSocket Il server a sua volta dopo aver ricevuto la richiesta di instaurare una connessione WebSocket dovrà valutarne tutti i campi e solo dopo questa 5
  • 12. verifica, potrà rispondere al client. Dovra assicurarsi, in particolare, che l’indirizzo del client non sia stato esplicitamente vietato e che la versione del protocollo ed eventuali subprotocolli o estensioni richieste dal client siano supportati. Nel caso sia esplicitamente richiesta una connessione sicura allora il server dovrà inanzitutto inizializzare il canale TLS. Dopo aver eseguito la routine esposta il server risponderà al client che a sua volta validerà le informazioni contenute nella risposta. Se tutti i requisiti sono soddisfatti allora lo stato della connessione verrà impostato ad OPEN e sia il server, che il client potranno iniziare a mandare dati. Figura 1.4: Esempio di diagramma sequenziale di WebSocket. Dopo l’hand- shake iniziale su HTTP la comunicazione diventa full-duplex Seppure WebSocket non aggiunga molto al di sopra di TCP, il suo hand- shake risulta quattro volte più lungo[1]. Una delle ragioni principali è data dal fatto che una connessione TCP dovrà essere negoziata in ogni caso prima di poter iniziare l’ handshake di WebSocket. Tuttavia dopo aver instaurato la connessione, le performance tra WebSocket e TCP non differiscono di molto, rendendo in pratica quasi impercettibile la differenza di livello logico. Ciò è dato dal fatto che il protocollo è stateful e rispetto a HTTP, gli header ven- gono ridotti all’osso spostando gran parte del controllo della comunicazione, alla fase di negoziazione. Il protocollo WebSocket, ha rappresentato dunque una svolta nella comu- nicazione bidirezionale, tanto da dimostrarsi diversi ordini di grandezza più 6
  • 13. performante in termini di latenze, rispetto alle precedenti tecniche basate sul pull, soprattutto in casi di connessioni di rete non ottimali[2]. Tutta- via con l’avvento dello streaming dal vivo, i requisiti di latenza si sono fatti sempre più esigenti ed in presenza di perdite di dati, la reliability del proto- collo sottostante TCP si è dimostrata un collo di bottiglia. Gli sviluppatori quindi hanno scelto di sacrificare i dati non ricevuti in tempo, a favore dei dati più aggiornati. Per fare ciò, è stato necessario rivedere ancora una volta i livelli logici sottostanti, dando vita a vari protocolli basati su UDP, tra i quali WebRTC, che negli ultimi anni si è dimostrato una valida alternativa a WebSocket. 7
  • 14. 1.3 WebRTC 1.3.1 Cos’è WebRTC? WebRTC, abbreviazione di Web Real Time Communication, è un framework open-source creato da Google nel 2011, composto da un aggregato di pro- tocolli, standard ed API, che messi assieme permettono a due nodi in rete, di stabilire un servizio di comunicazione in tempo reale, come ad esempio di messaggistica, di chiamata audio e video o di trasferimento file, senza l’au- silio di plugin aggiuntivi. Inizialmente fu concepito per i browser ma data la sua crescita in popolarità sono nate quasi subito librerie che ne permet- tono l’implementazione in ambienti back-end, soprattutto quelli basati su Javascript. A differenza dei protocolli tradizionali, la comunicazione qui è di tipo peer-to-peer. Con il termine peer-to-peer si indica tutti quei sistemi, nei quali gli elementi che compongono il sistema, condividono le risorse e svolgono contemporaneamente il ruolo di offerente e richiedente del servizio[3]. In altre parole, le tecnologie di questo genere hanno un’architettura decentralizzata e non prevedono l’uso di server intermediari, consentendo quindi ai client, denominati peer, di comunicare direttamente tra di loro. Anche WebRTC è in linea di principio serverless, anche se come si vedrà in seguito, l’uso di server ausiliari nella fase di inizializzazione della connessione, ne facilita l’implementazione. La API di WebRTC è composta da tre componenti: • getUserMedia: usata per acquisire la traccia audio e video dalla camera e dal microfono • RTCPeerConnection: abilita la comunicazione audio e video tra i peer; gestisce anche la sicurezza, la gestione della banda di rete e la parte di negoziazione della comunicazione, come lo scambio delle interfaccie di rete e dei codec multimediali utilizzati dai peer • RTCDataChannels: usata per la comunicazione bidirezionale tra i peer di tutti quei dati arbitrari che non fanno parte del flusso multimediale In questa tesi l’attenzione verrà posta principalmente sulla terza componente, che è quella che ci permetterà di trasmettere i dati relativi alle posizioni dei giocatori sul campo da gioco. Va notato, che WebRTC non è un protocollo nel senso stretto del termine, bensı̀ più una serie di direttive. Questo non solo perché aggregato di più protocolli anche facenti parte dello stesso livello logico, ma soprattutto perché lascia ampio margine di manovra agli sviluppatori, evitando di specificare il ‘come‘ in alcuni passi cruciali per l’implementazione di un’applicazione 8
  • 15. funzionale, soprattutto in quelli relativi alla negoziazione. Nella Figura 1.5 è schematizzata la pila dei protocolli che lo compongono, la maggior parte dei quali verrà approfondita in seguito. Figura 1.5: Pila dei protocolli costituenti WebRTC 1.3.2 ICE, STUN e TURN Una delle prime difficoltà che si incontrano nella realizzazione di un sistema peer-to-peer, come WebRTC, è quella di mettere in comunicazione i vari nodi. Questo potrebbe non essere un problema nel caso in cui i nodi siano nella stessa rete, ma lo diventa nello scenario tipico in cui risiedono in reti diverse. Un nodo in rete infatti, è raggiungibile solamente all’indirizzo IP pubblico a lui associato. Nelle architetture tradizionali questo problema non si pone, perché i server rendono noto il proprio IP pubblico tramite il protocollo DNS. Tuttavia in WebRTC non si hanno server e alcuni nodi potrebbero non avere un IP pubblico dedicato ed essere quindi soggetti ad attraversamento NAT. Il Network Address Translation è uno standard che mappa indirizzi IP di una rete in un’altra, solitamente indirizzi IP privati in indirizzi pubblici[4], consentendo ad un dispositivo che ne è sprovvisto, di poter navigare in re- te. Per fare ciò si avvale di una struttura dati denominata NAT Table che mapperà la quadrupla (IP interno, Porta interna, IP esterno, Porta esterna) 9
  • 16. in modo da poter reindirizzare le risposte derivanti dalla rete esterna, al nodo interno che le aveva richieste. Il NAT agisce sul fronte della rete locale ed è del tutto trasparente ai dispositivi su cui opera. Per verificare se si trova dietro un NAT e ricavarne l’indirizzo pubblico, un nodo può avvalersi di un server che implementa il protocollo Session Traversal Utilities for NAT. Un server STUN, è un server che si occupa semplicemente di rispondere con l’indirizzo IP dal quale proviene la richiesta. Hanno costi di gestione minimi e in rete se ne trovano varie implementazioni gratuite, che permettono l’implementazione pratica dell’ Interactive Connectivity Establishment. Il protocollo ICE, è una tecnica usata per trovare la via ottimale per met- tere in comunicazione diretta due peer. Si occupa di trovare tutte i fronti di rete, detti candidati ICE, sui quali è in ascolto il nodo, interrogando l’inter- faccia di rete del dispositivo ed eventuali sever STUN. Fatto ciò, il layer ICE manderà, usando tecniche di signaling [1.3.3], i dati collezionati allo stesso layer dell’interlocutore. Quest’ultimo, risponderà a sua volta con i suoi di candidati e dopo che lo scambio è andato a buon fine, i due layer proveranno a stabilire una connessione utilizzando i candidati ricevuti, ordinati in ordine di latenza, provando ad esempio per primi gli indirizzi IP privati nel caso i due peer risiedano nella stessa rete locale. Figura 1.6: Esempio di ICE candidates gathering Lo stabilire della connessione peer-to-peer potrebbe risultare impossibile nel caso di alcune combinazioni di tipologie di NAT. Esistono infatti quattro 10
  • 17. tipi di NAT che si differenziano per la restrittività sulle connessioni in entrata: • Full-Cone NAT : mappa indistintamente l’IP del NAT nell’IP del Client interno alla rete in base alla PORT in entrata • Address Restricted NAT: lascia passare il pacchetto in entrata solo nel caso in cui l’ IP che ha generato il pacchetto è presente nella tabella NAT; lascia cioè passare i pacchetti in entrata solo se un qualunque nodo interno alla rete ha mandato almeno una richiesta a quel’ IP esterno • Port Restricted NAT: simile al precedente ma prende in considerazione anche la porta, ossia lascia passare i pacchetti in entrata solo se un nodo interno ha già mandato una richiesta a quel indirizzo IP esterno e a quella porta esterna • Symmetric NAT: lascia passare un pacchetto in entrata solamente se la quadrupla esiste nella tabella NAT, ovvero un pacchetto in entrata può passare solo verso un nodo interno che lo ha richiesto precedentemente Come sarà spiegato nella prossima sottosezione i due peer si scambiano le informazioni per stabilire la connessione per via indiretta, utilizzando un attore di terze parti. Nel caso di alcune combinazioni, come mostrato in tabella 1.1 questo non è possibile perché i pacchetti che non trovano una corrispondenza specchiata nella tabella NAT, cioè che non rappresentano una risposta ad una richiesta generata dal nodo dietro al NAT, verranno bloccati. In questo caso vi è la necessità di utilizzare un server che implementa il Traversal Using Relays around NAT. Un server di questo tipo, detto server TURN risiede all’esterno del NAT e reindirizza il traffico del peer. In questo modo il peer manterrà una connessione solamente con il server TURN, che gli farà da tramite nella comunicazione WebRTC. Full-Cone Address Port Symmetric Full-Cone STUN STUN STUN STUN Address STUN STUN STUN STUN Port STUN STUN STUN TURN Symmetric STUN STUN TURN TURN Tabella 1.1: Combinazioni che richiedono l’uso di un server TURN I server TURN, a differenza di quelli STUN hanno costi di gestione più significativi e le soluzioni più affidabili sono a pagamento. Inoltre l’introdu- zione del server TURN spezza il paradigma del peer-to-peer, causando un 11
  • 18. aumento di latenze notevoli nella comunicazione. La necessità di un server TURN tra i candidati ICE di un peer per poter avere un sistema robusto ad ogni evenienza e indipendente dalle reti locali in cui risiedono i peer, rappresenta forse uno dei punti deboli di WebRTC. 1.3.3 Signaling e SDP Dopo aver collezionato tutti i potenziali candidati ICE il peer che vuole ini- ziare a comunicare deve formalizzare il proprio ‘biglietto da visita‘ usando uno standard denominato Session Description Protocol. L’SDP è una lunga stringa di paia key = value separati dal carattere di nuova linea n, che oltre ai vari candidati ICE, conterrà anche informazioni relative al canale media come i codec supportati dal peer, gli algoritmi di cifratura etc. Dopo aver creato un offer, il peer dovrà reperirla all’interlocutore. Lo standard WebRTC non entra nel dettaglio su come ciò debba avvenire. Tra gli svilup- patori si è consolidata la soluzione che vede un server WebSocket dedicato, chiamato Signaling Server, che si occuperà solo di fare da portavoce ai due peer. Il primo peer invierà la propria offerta di disponibilità al Signaling Server, che la inoltrerà all’altro peer. Dopo averla ricevuta, quest’ultimo ge- nererà un answer e la manderà indietro sempre con l’ausilio del Signaling Server. Una volta essersi scambiati le reciproche informazioni e dopo aver trovato la via più efficiente per comunicare, i due peer potranno generare il canale di comunicazione, il Data Channel. Figura 1.7: Negoziazione della connessione WebRTC 12
  • 19. Inizialmente lo stabilire della connessione WebRTC richiedeva più tempo, rispetto agli altri protocolli di comunicazione. Ciò era dovuto al fatto di dover collezionare tutti i possibili candidati ICE, prima di stabilire la connessione, soprattutto quelli relativi ai server STUN e TURN. In alcuni casi, come ad esempio quando i peer fanno parte della stessa rete locale, oppure in presenza di NAT non eccessivamente restrittivi, alcuni di questi candidati risultavano ridondanti. Per ovviare a questo problema è stato introdotto il Trickle ICE. Il Trickle ICE è un estensione del protocollo ICE che permette di instau- rare una connessione tra i peer, prima ancora di aver terminato la ricerca di tutti i possibili candidati ICE. Non appena un peer avrà trovato un possibile candidato, lo manderà all’interlocutore, con il quale proverà di instaurare una connessione, cercando parallelamente altri possibili fronti di comunica- zione. Nel caso un altro candidato fosse trovato, lo si manderà come possibile fall-back di connessione, utilizzando direttamente il Data Channel se già in- staurato oppure il signaling server. I peer dovranno in questo caso essere in grado di differenziare i messaggi applicativi, da quelli contenenti i nuovi can- didati. Il Trickle ICE ha diminuito i tempi di negoziazione di diversi ordini di grandezza, sacrificando in parte la robustezza della connessione. In questo progetto non siamo soggetti a vincoli temporali sullo stabilire la connessione e il focus è sullo scambio dati, per questo il Trickle ICE sarà disattivato. Un altro aspetto da notare è che per costruzione, un’offerta SDP avrà un identificativo univoco e in condizioni normali non potrà essere riutilizzata su più connessioni. Esistono però delle implementazioni del layer ICE che lo permettono, fenomeno denominato ICE forking. L’ ICE forking non è ancora implementato in WebRTC e nel nostro caso la torretta server non potrà rendersi disponibile su più client con la stessa offerta memorizzata nel signaling server, il che semplificherebbe la struttura del sistema. 1.3.4 Data Channel, SCTP e DTLS I messaggi testuali tra i due interlocutori WebRTC vengono scambiati tramite il Data Channel. A differenza dei tradizionali protocolli di comunicazione basati su TCP, il Data Channel utilizza STCP. Lo Stream Control Transmission Protocol è un protocollo di comunica- zione sviluppato dal gruppo di lavoro IETF Signaling Transport ed orienta- to alla connessione, ma che condivide molte caratteristiche con i protocolli orientati ai messaggi [5]. Inizialmente fu pensato per le infrastrutture tele- foniche nelle reti IP, come il VoIP, ma la sua flessibilità lo rese interessante anche per applicazioni di natura diversa. Viene implementato sopra UDP ma concettualmente si pone sullo stesso livello logico. A differenza dei già noti protocolli orientati alla connessione, primo tra tutti TCP, esso offre la 13
  • 20. possibilità di configurare l’affidabilità della connessione, la cosiddetta reliabi- lity e l’ordinamento o meno della sequenza dei dati in arrivo. Risulta dunque un ibrido che in base ai parametri di inizializzazione può avere un compor- tamento più simile a TCP oppure più vicino a UDP. Permette inoltre di stabilire un terzo tipo di comunicazione, detta comunicazione parzialmente affidabile, in cui il mittente proverà a ritrasmettere un messaggio che non ha ricevuto conferma, ma solo per un numero prefissato di volte oppure per un certo arco di tempo, per poi passare ai messaggi seguenti [6]. Usato assieme al protocollo ICE, supporta anche il multy-homing, ovvero la possibilità di aggiungere più percorsi per raggiungere il nodo di destinazione. In questo caso e se configurato in modalità affidabile, in caso di perdite, il protocollo potrebbe provare più percorsi al fine di trovare quello che gli garantisce la maggiore stabilità. Similmente a TCP anch’esso offre un controllo di con- gestione, il congestion avoidance e la fast retransmit, il che si traduce in un comportamento slow start. Tuttavia, a differenza di TCP la finestra di con- gestione iniziale, initial congestion window (cwnd), è impostata al doppio dell’unità massima di trasmissione, MTU e viene incrementata in base al numero di byte confermati piuttosto che al numero di conferme in se come avviene in TCP [7]. Le dimensioni iniziali più ampie ed il loro aumento più aggressivo comportano delle dimensioni della finestra mediamente maggiori e come conseguenza un throughput più elevato rispetto a TCP. Inoltre vo- lendo la finestra iniziale può essere configurata. Quest’ultima possibilità è stata oggetto di argomento nell’ambito WebRTC e come vedremo in seguito può inciderne sulle prestazioni. Il controllo del flusso e quello della congestio- ne permettono di stabilire il throughput ottimale relativo alla stabilità della rete. TCP UDP SCTP Reliability Reliable Unreliable Configurable Delivery Ordered Unordered Configurable Transmission Stream Messages Messages Flow Control Yes No Yes Congestion Control Yes No Yes Tabella 1.2: Confronto tra SCTP e i principali protocolli di comunicazione Prima di essere passati al layer UDP, i messaggi SCTP di WebRTC, de- vono obbligatoriamente passare attraverso il DTLS. Il Datagram Transport Layer Security è un protocollo di comunicazione progettato per proteggere la privacy dei dati e prevenire intercettazioni e manomissioni della trasmis- sione da parte di malintenzionati. Si basa sulla criptazione pubblica per 14
  • 21. l’autenticazione dei nodi e per la negoziazione della chiave privata, che verrà poi utilizzata per criptare i messaggi che successivi. Tuttavia, a differen- za dei protocolli più noti della stessa famiglia, come TLS o SSL, esso viene implementato su UDP ed è progettato specificamente per dare supporto ai protocolli orientati ai messaggi. Si noti che la criptazione avviene agli estremi, endpoint, della connessio- ne: la presenza o meno di server TURN non influisce su di essa. Quest’ultimi infatti non avranno accesso al contenuto dei datagrammi, né potranno mani- polarli e si limiteranno solo a reindirizzarli. A differenza del canale PeerCon- nection, usato per scambiare dati multimediali e che usa un protocollo simile a DTLS, ma che non cripta i header dei frame, dai quali si può estrarre delle informazioni, il DTLS cripta tutto il payload di UDP, rendendo il Data Chan- nel intrinsecamente più sicuro. In fine l’essere obbligatorio rende il sistema che lo utilizza più robusto agli errori o sviste da parte degli sviluppatori. Il supporto nativo da parte dei browser, rende WebRTC, un ottimo can- didato per trasformare tutti quei client dedicati di applicazioni UDP in ap- plicazioni web, indipendenti dal sistema operativo. La possibilità di stabilire una connessione non affidabile previene inoltre problematiche di tipo head of the line blocking, che verranno approfondite in seguito, ma che in sostan- za vedono una mancata conferma di un pacchetto, bloccare tutto il flusso dei messaggi. La flessibilità datagli dai protocolli sottostanti, specialmente SCTP, permette al Data Channel di poter sacrificare l’affidabilità e l’ordina- mento, per diminuire la latenza di trasmissione, rendendolo ideale per tutte quelle applicazioni di streaming dal vivo, come la nostra. 1.3.5 Sicurezza Uno dei parametri fondamentali, che viene sempre tenuto in considerazione dagli sviluppatori quando decidono di adottare un protocollo, è il livello di sicurezza che quest’ultimo garantisce. La natura open-source di WebRTC ci ha permesso di valutare questo aspetto a livello di protocolli usati e nella discussione abbiamo ipotizzato una comunicazione ideale, senza specificare alcun threat model. Come tutti i protocolli di comunicazioni però, anche WebRTC presenta delle possibili vulnerabilità. La parte più critica della comunicazione WebRTC è sicuramente la ne- goziazione. Un attaccante, che abbia controllo del signaling server potrebbe spacciarsi per la persona con la quale si vuole dialogare. Questo scenario apre le porte a tutta una serie di threat model, come Man in the middle, se l’attaccante è interessato a manipolare il traffico, Reply attack se l’attaccante vuole solo osservare la comunicazione oppure Session hijacking se l’attaccan- te spodesta l’interlocutore e ne prende il posto. Per ovviare a tutto ciò si sta 15
  • 22. cercando di stabilire una relazione biunivoca tra peer ed identità, che possa essere verificabile da entrambe le parti. In particolare tra le soluzioni più acclamate vi è quella dell’utilizzo di protocolli basati su delega di accesso, come OAuth, che cede la responsabilità di autenticazione ad un servizio ester- no detto Identity provider. Come contro a questo approccio, vi è il fatto che entrambe le parti devono fidarsi di quel servizio, il che si traduce in pratica nell’avere un account registrato. Un’altra possibilità promettente,che non prevede attori di terze parti, è quella di usare un meccanismo basato su bloc- kchain smart contract, che sono pubblici ed immutabili per natura. Questo approccio è stato esplorato in [8], sfruttando la rete blockchain Ethereum e si è dimostrato che la latenza introdotta dall’autenticazione che sfrutta questo metodo risulta trascurabile. Esistono poi, tutta una serie di vulnerabilità che sono proprie di We- bRTC. Tra quelle che hanno suscitato più timori vi è sicuramente quella del WebRTC Leak. La vulnerabilità colpisce soprattutto gli utenti che utilizzano una VPN e permette all’attaccante di rivelare l’indirizzo IP pubblico delle vittime. Questo accade in presenza di VPN configurate in modo errato, che non dirottano il traffico STUN attraverso il tunnel VPN. Attirando le vitti- me sul suo sito l’attaccante può quindi cercare di instaurare una connessione WebRTC. Il browser dell’utente inizierà a sua insaputa a raccogliere tutti i candidati ICE senza passare per la VPN, rivelando l’IP pubblico vero della vittima. Oltre a ciò l’attaccante ricaverà anche l’indirizzo IP privato della vittima all’interno della rete, che potrebbe essergli molto favorevole, soprat- tutto in contesti aziendali, perché gli permetterebbe di mappare la rete e gli faciliterebbe attacchi più mirati. Come dimostrato da Al-Fannah Nasser Mo- hammed in [9], questo non è un problema residuale ma al contrario affligge un ampio spettro di servizi VPN e browser. Un’altra vulnerabilità è data dal fatto che WebRTC potrebbe indiretta- mente facilitare l’invio di malware. Nelle piattaforme tradizionali di condi- visione di file, che si avvalgono di un server intermedio vi è un controllo da parte del server, dei file spediti . Nelle comunicazioni di tipo peer-to-peer invece, questo controllo viene meno e dovrebbe essere eseguito a livello di nodo. Questo aspetto, che il più delle volte viene trascurato [10] e unito al fatto che l’apertura del Data Channel non viene notificata direttamente all’utente, potrebbe permettere all’attaccante di mandare file malevoli. Le varie vulnerabilità esposte potrebbero essere risolte in futuro, per esempio richiedendo all’utente il permesso di rispondere ad un offerta di comunicazione WebRTC. Tuttavia nel frattempo alcuni utenti o addirittura produttori potrebbero decidere di disabilitare WebRTC sui propri browser il che porterebbe alla perdita di tutta una fetta di utenti. Questo fatto de- v’essere tenuto in considerazione nella prossima sezione che si occuperà di 16
  • 23. confrontare il protocollo WebRTC con quello dei WebSocket. 17
  • 24. 1.4 Confronto In questa sezione vogliamo confrontare i protocolli presentati precedente- mente. In letteratura, si possono trovare vari studi di prestazione dei singoli protocolli, che ci aiuteranno a stabilire gli indici che useremo per il confron- to. Tenendo in conto i requisiti temporali da soddisfare ed il fatto di volere sempre i dati più aggiornati, anche a fronte di perdite, potremmo decidere quale di essi è più conforme ai nostri fini. 1.4.1 Stato dell’arte Come visto, le prestazioni del protocollo WebSocket non differiscono di molto rispetto a TCP e a differenza del TCP puro, Websocket ha il vantaggio di essere applicabile direttamente nel contesto Web. Inoltre, vari studi come [1], hanno dimostrato che, a differenza dei protocolli basati sul polling HTTP, esso presenta meno dati ridondanti e in sessioni lunghe o in condizioni di rete non ottimali, il traffico di rete si riduce notevolmente. Le pubblicazioni di WebRTC invece, sono meno numerose e si focalizzano soprattutto sulla trasmissione di contenuti multimediali, che come abbiamo visto utilizza un altro canale. Per quanto riguarda il Data Channel, lo studio più rilevante è sicuramente quello di Eskola e Nurminen [11], in cui si scopre che la scelta di lasciare inalterata la dimensione iniziale della finestra SCTP, ereditata dal protocollo originale, può influire negativamente sulla trasmis- sione dei dati. In caso di raddoppio della latenza di rete, il throughput del Data Channel diminuisce di un’ordine di grandezza. Tuttavia nel nostro progetto i dati che vogliamo trasmettere hanno dimensioni massime fisse ed il focus sarà posto sul diminuire il tempo che impiegano dalla sorgente al consumatore. Inoltre in [12], è stato notato come WebRTC, confrontato con altri protocolli simili, sia più dispendioso a livello di CPU il che può avere delle ripercussioni sull’autonomia dei dispositivi mobile. Per concludere noi valuteremo i tempi di comunicazione, gli effetti che si hanno su di essa in presenza di degradazione della rete e l’uso delle risorse di sistema del consumatore. Verranno tenute in considerazione anche la facilità di implementazione e gli eventuali costi di una soluzione rispetto all’altra. 1.4.2 Setup Per l’esperimento si è utlizzato un server locato negli Stati Uniti d’America (Virginia) con sistema operativo Ubuntu v20.04.4 LTS e indirizzo IP pub- blico, sul quale sono stati eseguiti due processi, uno relativo al protocollo WebSocket e l’altro relativo a WebRTC. Per l’esecuzione è stato utilizzato 18
  • 25. Node.js v16.5.0, che è un sistema a runtime, open source, multi piattaforma orientato agli eventi, pensato per l’esecuzione di codice Javascript e costrui- to sul motore Javascript V8 di Google Chrome. Utilizzando il gestore di pacchetti predefinito di Node, il Node Package Manager (npm), è possibile arricchirlo con librerie esterne. In particolare in questo esperimento sono state utilizzate le seguenti librerie: • ws: usata per l’implementazione del protocollo WebSocket • simple-peer: usata per l’implementazione del protocollo WebRTC. Si basa su node-webrtc, che fa il porting di webrtc dal mondo browser a quello Node.js, ma ne semplifica l’utilizzo, dando la possibilità di modificare facilmente alcuni parametri relativi alla connessione, come ad esempio il Trickle ICE • simple-statistics: usata per le calcolare le stime statistiche dei tempi di latenza Entrambe le librerie relative ai protocolli sono orientato agli eventi. In particolare per l’esperimento che riguarda i WebSocket si ha il seguente codice lato server: // server.js webSocketServer.on("connection", (webSocket) => { console.log("New client connected"); let counter = 0; let data = {}; const intervalID = setInterval(() => { data = { counter: counter, timestampStart: Date.now() }; webSocket.send(JSON.stringify(data)); counter++; if (counter > 1000) { webSocket.close(); clearInterval(intervalID); } }, config.BIT_RATE); }); che fa si che il server inizierà a mandare pacchetti al client, non appena questo vi si connetterà. I pacchetti avranno dimensioni simili a quelli del- l’applicazione reale e conterranno un identificativo, che sarà incrementato ad 19
  • 26. ogni pacchetto e che servirà per valutare le perdite ed il timestamp dell’invio in millisecondi, usato per stimare le latenze. Il server manderà i dati secondo il bitrate dell’applicazione e dopo 1000 pacchetti si fermerà. Per quanto il codice client si ha: // client.js webSocket.on("message", (data) => { const msg = JSON.parse(data); if (msg.counter > counter) { msg.timestampEnd = Date.now(); list[counter] = msg; } counter = msg.counter; }); webSocket.on("close", () => { console.log("Closing connection from client!"); const differences = []; for (let index = 0; index < list.length; index++) { const e = list[index] if (e !== undefined) { differences[index] = e.timestampEnd - e.timestampStart; } } const filteredDiff = differences .filter((x) => x !== undefined); const max = statistics.max(filteredDiff); const min = statistics.min(filteredDiff); const mean = statistics.mean(filteredDiff); const var = statistics.variance(filteredDiff); }); che si salverà solo i pacchetti più recenti, il che sarà utile in caso di perdite soprattutto nel codice WebRTC, e ne memorizzerà il timestamp di arrivo. Quando avrà ricevuto tutti i dati, valuterà i tempi di arrivo dei pacchetti ricevuti e arrivati per tempo e ne trarrà alcune stime statistiche,. Il codice è stato riusato in parte anche nell’esperimento con WebRTC con la differenza che al posto della variabile webSocket, gli eventi sono stati modellati sulla variabile che rappresenta il peer. Si ha quindi: 20
  • 27. // server.js // codice negozziazione omesso ... const peer = new Peer({ initiator: false, wrtc: wrtc, config: { iceServers: [{ urls: "stun:stun.l.google.com:19302" }] }, trickle: false, ordered: false, maxRetransmits: 0, }); peer.on("connect", () => { // codice omesso per brevità }) dove Peer è il costruttore della variabile che modella il nodo peer-to-peer e che prende in ingresso dei parametri relativi al ruolo, ai server STUN, al Trickle ICE e al tipo di connessione che si vuole creare, nel nostro caso non affidabile e non ordinata, simile ad UDP. Similmente a lato client si ha: // client.js // codice negozziazione omesso ... const peer = new Peer({ initiator: true, wrtc: wrtc, config: { iceServers: [{ urls: "stun:stun.l.google.com:19302" }] }, trickle: false, ordered: false, maxRetransmits: 0, }); peer.on("data", () => { // codice omesso per brevità 21
  • 28. }) peer.on("close", () => { // codice omesso per brevità }) Per quanto riguarda la negoziazione è stato usato il protocollo WebSocket. Il server implementa sia il signaling che l’interlocutore: dopo lo scambio iniziale delle offerte e delle risposte tramite WebSocket si passerà a WebRTC. L’architettura peer-to-peer viene quindi ‘adattata‘, a quella client-server, più conforme ai nostri fini. Inoltre, dopo aver eseguito l’esperimento, lo si è voluto ripetere in condi- zioni di rete non ottimali. Per fare ciò, si è utilizzato Netem, un program- ma Linux che da linea di comando permette di simulare perdite, ritardi e corruzioni dei dati. In particolare utilizzando il comando: sudo tc qdisc add dev wlp5s0 root netem delay 50ms loss 35% si è aggiunto un ritardo di 50 ms e una perdita del 35 % dei pacchetti all’interfaccia di rete wireless. 1.4.3 Risultati L’esperimento è stato ripetuto in varie fasce orarie, per evitare distorsioni nei dati dovute alla congestione della rete. Tuttavia l’orario si è dimostrato non particolarmente incidente e i risultati presentati saranno presi da una delle fasce in cui si è svolto l’esperimento. Per quanto riguarda il protocollo WebSocket si ha per ogni pacchetto, le seguenti differenze di tempo di arrivo e partenza, in condizioni ottimali: 0 100 200 300 400 500 600 700 800 900 1,000 0 50 100 pacchetto latenza (ms) 22
  • 29. con un picco massimo di 47 ms ed uno minimo di 42 ms. La media è di 43.7 ms, con una varianza del 0.4 ms2 . Aumentando il ritardo di 50 ms e alzando il numero di pacchetti persi si ha: 0 100 200 300 400 500 600 700 800 900 1,000 0 50 100 pacchetto latenza (ms) con tempo di transito massimo di 129 ms, minimo di 92 ms. In media un pacchetto transita per 102.2 ms e la varianza si aggira al 125.5 ms2 . I picchi sono dovuti probabilmente a ritrasmissioni dei pacchetti, essendo il protocollo affidabile ed ordinato. Per quanto riguarda WebRTC in condizioni ottimali si ha: 0 100 200 300 400 500 600 700 800 900 1,000 0 50 100 pacchetto latenza (ms) con un massimo di 44 ms, un minimo di 41 ms. In media un pacchetto transita per 42 ms, con una varianza del 0.3 ms2 . Non si è registrata alcuna perdita. In condizioni di rete non ottimali invece si ha: 23
  • 30. 0 100 200 300 400 500 600 700 800 900 1,000 0 50 100 pacchetto latenza (ms) con tempo massimo 98 ms, minimo 91 ms, media del 94.5 ms e varianza 4.1 ms2 . La comunicazione è stata impostata come non affidabile e le stime sono state calcolate senza tenere conto dei pacchetti che non hanno ricevuto conferma o che non sono arrivati per tempo. Nel nostro caso in condizioni di rete ottimali i protocolli risultano quasi indistinguibili, mentre in quelle non ottimali WebRTC si dimostra legger- mente migliore. Tuttavia anche nel caso peggiore, che è stato appositamente esagerato, il protocollo WebSocket si è dimostrato degno, con latenze media- mente intorno alle centinaia di millisecondi. Per quanto riguarda l’uso delle risorse di sistema ed in particolare quello della CPU, si ha che WebRTC è leggermente più esigente, ma risulta ancora gestibile, dato che un computer datato di fascia media con CPU Intel i7-4700HQ 2.40 GHz ha esibito un picco massimo di 40 % in un singolo core. La torretta server, che farà da sorgente dati, è posizionata all’interno dell’azienda e dietro ad un NAT di tipo simmetrico. Risulta dunque, come spiegato in 1.3.2, necessario dotarsi di un server TURN per rendere le comu- nicazione robusta. Considerando inoltre i risultati promettenti in entrambi i casi, i tempi di negoziazione della connessione e che ambedue le API risul- tano interscambiabili e non influenzano la logica dell’applicazione, abbiamo scelto di implementare il prototipo con il protocollo WebSocket, posticipando la scelta definitiva ad applicazione finita. 24
  • 31. 1.5 WebTransport WebTransport è un protocollo di comunicazione bidirezionale nuovo, ancora in fase sperimentale, che in futuro potrebbe spodestare WebSocket e risul- ta quindi degno di nota. A differenza di WebRTC, esso mantiene l’impo- stazione client-server e crea la connessione utilizzando il protocollo QUIC, recentemente introdotto da Google. 1.5.1 Perchè QUIC? Agli albori del Web, nel 1989, Tim Berners-Lee concepı̀ una prima bozza del protocollo HTTP, che sarebbe stato in seguito ampiamente adottato come sistema predefinito per la trasmissione di dati attraverso il web. Implemen- tato sopra IP e TCP, il protocollo inizialmente era scarno e le richieste e risposte contenevano solo il payload senza altre informazioni aggiuntive sullo stato della connessione. Nella prima standardizzazione del HTTP 1.0 sono state aggiunte queste informazioni sotto forma di Headers. Tuttavia questa versione imponeva l’utilizzo di una sola connessione TCP per risorsa. Con il crescere del Web ed ed essendo l’apertura della connessione TCP, la parte più dispendiosa in termini di risorse, si creò rapidamente un collo di bottiglia che venne in seguito risolto con la seconda standardizzazione. L’HTTP 1.1 permette di riutilizzare una connessione TCP e di stabilire più connessioni TCP, solitamente sei, contemporaneamente. Tuttavia quando le connessioni parallele sono tutte utilizzate il browser deve restare in stallo aspettando le relative risposte. Questo fenomeno, denominato Head of Line Blocking fa si che richieste concettualmente indipendenti, diventino dipendenti per via della tecnologia su cui transitano. Inoltre le connessioni TCP avendo una so- la scheda rete, sono virtuali e dato che la capacità della singola connessione risulta maggiore del traffico nelle altre 6 si potrebbe pensare di comprimere il tutto in un unica connessione TCP. Da questa idea è nato SPDY. SPDY, successivamente rinominato in HTTP 2, tra le molteplici miglio- rie, introduce il multiplexing, ossia il comprimere più traffici HTTP paralleli, detti stream, in una sola connessione TCP. Multiple richieste HTTP, ognuna etichettata, potranno quindi essere mandate contemporaneamente sulla stes- sa connessione TCP. Il server dovrà differenziare i byte relativi ad ogni richie- sta e generare le relative risposte, che a sua volta potranno essere mandate contemporaneamente. Lo scopo del multiplexing è quindi quello di introdur- re un certo parallelismo nelle azioni e di contrastare la mole di dati sempre crescente, delle pagine web. L’indipendenza delle richieste però, anche in questo caso, risulta fittizia: data la natura affidabile ed ordinata di TCP, nel caso uno stream subisca una perdita, la ritrasmissione dei pacchetti relativi 25
  • 32. bloccherebbe gli altri stream, nei quali viaggiano altre richieste indipendenti. Il blocco Head of Line quindi, seppur è stato risolto a livello di applicazione, permane nel layer di trasporto. Per questo motivo è stato introdotto HTTP 3, che sostituisce TCP con un nuovo protocollo meno restrittivo, denominato QUIC. Figura 1.8: Head of Line Blocking nelle due declinazioni: a sinistra HTTP 1.1 con il blocco delle sei connessioni TCP e a destra HTTP 2, con il blocco dei stream nella singola connessione TCP QUIC è un protocollo di rete a livello di trasmissione, con caratteristi- che simili a TCP, ma implementato sopra UDP, che si prefissa il compito di prendere il meglio dei due protocolli. Analogamente a TCP, QUIC im- plementa un sistema di controllo di congestione, di conferma di ricezione e ritrasmissione dati, ma lo fa a livello di stream, evitando cosı̀ il collo di botti- glia precedentemente descritto. Oltre alla minore latenza, essendo i pacchetti trasmessi su UDP, QUIC facilita anche l’inizializzazione della connessione. Al giorno d’oggi infatti, per stabilire una connessione basata su TCP, biso- gna innanzitutto portare a termine l’ handshake iniziale, per poi rendere la connessione sicura con TLS, che a sua volta richiederà delle iterazioni. Con QUIC la cifratura del canale è obbligatoria e viene negoziata direttamente all’handshake, permettendo di risparmiare molteplici round trip tra il client ed il server. Inoltre se i due hanno già interagito recentemente, QUIC può mandare dati utili già alla richiesta di connessione. Inoltre etichettando i pacchetti con un identificativo di connessione, permette di mantenere aperta 26
  • 33. la connessione nel caso di cambio del supporto di rete da parte del disposi- tivo. QUIC è quindi altamente versatile e configurabile e potrebbe portare benefici non da poco, a tutti quei protocolli di comunicazione basati su TCP, come ad esempio WebSocket. WebTransport si potrebbe riassumere come quest’ultimo, migrato su QUIC. 1.5.2 Vantaggi WebTransport è un protocollo di comunicazione bidirezionale costruito sopra QUIC. Può essere configurato per comunicare con l’ausilio di datagrammi, oppure attraverso stream di dati. I datagrammi non garantistico nessuna garanzia sulla ricezione e sull’ordi- ne nel quale vengono ricevuti, ma rappresentano un’ottima opzione nel caso di applicazioni che necessitano di basse latenze. Si può pensare a questa opzione, come al traffico UDP, ma criptato e con l’aggiunta di un controllo di congestione. Gli stream d’altro canto sono affidabili e ordinati ed appropriati per quelle applicazioni che non possono scendere a compromessi in questi termini. In questo caso il traffico sarà simile a quello TCP, ma con overhead minore e senza problematiche di Head of Line Blocking nel caso di più stream. A differenza di WebRTC la pila di protocolli che lo compongono è mi- nore, il che dovrebbe rendere il protocollo più robusto e più maneggevole. Inoltre, è supportato nativamente all’interno di Web Worker, che ne per- mette l’esecuzione indipendentemente dalla presenza o meno di una pagina HTML. Purtroppo al momento di scrittura di questa tesi esiste solo un pri- mo prototipo delle WebTransport API, scritto in Go e funzionante solo sui browser basati su Chromium, tuttavia Mozilla ha etichettato il protocollo come Worth prototyping. Resta quindi un protocollo con molto potenziale e degno di attenzione. 27
  • 34. Capitolo 2 Visualizzazione dei dati In questo capitolo si esplorerà i metodi migliori per rappresentare i dati ri- cevuti, mediante l’elemento canvas introdotto nelle specifiche di HTML 5. Dopo un’infarinatura della tecnologia Canvas e dei suoi pregi e difetti ri- spetto ad altre soluzioni per il disegno web, si discuterà la possibilità di usare librerie derivate da essa, che semplificano le API native. In particolare verranno discusse e confrontate due delle librerie canvas specializzate nella grafica bidimensionale più popolari, FabricJs e KonvaJs. Le specifiche, se- condo le quelli verranno messe alla prova le due librerie verranno ricavate dai requisiti relativi al front-end di reattività e fluidità della rappresentazione, misurando i tempi di inizializzazione della pagina e visualizzazione dei dati ricevuti. 28
  • 35. 2.1 Canvas Canvas è un elemento dello standard HTML5 che permette il rendering dina- mico di immagini bitmap attraverso Javascript. Fu introdotto inizialmente da Apple per uso all’interno del loro componente proprietario WebKit, ai fini di migliorare il browser Safari, ma data la sua versatilità fu presto adot- tato anche dagli altri browser e standardizzato dal WHATWG nelle nuove specifiche proposte per le tecnologie della prossima generazione. Il Canvas consiste in una regione disegnabile, le cui dimensioni vengono specificate dagli attributi height and width. Il codice Javascript può ac- cedere all’area con un set completo di funzioni, permettendo la generazione dinamica di disegni. Come struttura sottostante viene utilizzata una semplice bitmap, memorizzata nel browser, sulla quale verrà disegnato, richiamando i comandi di disegno nativi del sistema operativo. Più specificamente quando il browser farà il parsing di un documento HTML contenente un elemento <canvas>, dovrà allocare sullo schermo una mappa di pixel, che coprirà l’a- rea specificata. Per fare ciò può agire in modo autonomo, per esempio con una chiamata malloc(), oppure si può avvalere delle API di grafica, nati- ve del sistema operativo, come ad esempio DirectX, Gtk, Kde Plasma, Qt etc. Dopo che la superficie di disegno è stata creata, viene resa accessibile all’interprete Javascript attraverso un puntatore. Quando l’interprete Java- script vedrà l’invocazione di un metodo canvas, lo delegherà al browser, che lo passerà a sua volta al sistema operativo sottostante. Il dialogo tra il brow- ser ed il sistema operativo è trasparente allo sviluppatore che per disegnare, impiegherà solamente codice Javascript . A differenza delle precedenti tecnologie per la grafica web, come il plug- in Flash, Canvas non richiede alcuna estensione aggiuntiva ed è ampiamente supportato da tutti i browser. Il plug-in Flash infatti, veniva integrato come oggetto embedded esterno e non poteva comunicare con gli altri elementi della pagina, mentre Canvas, essendo integrato nello standard HTML5 e parte integrante del DOM, può interagire con esso. Questo estende le possibili animazioni e l’iterazione con l’utente e rende il caricamento della pagina più veloce e di conseguenza la navigazione più fluida. Un’altra tecnologia per la grafica web, simile al Canvas e che è stata an- ch’essa introdotta recentemente nello standard HTML5 è quella del SVG. La Scalable Vector Graphics, è un particolare tipo di grafica, che si pone l’obbiet- tivo di descrivere figure bidimensionali. A differenza del Canvas, che viene rappresentato nel DOM come un singolo elemento, una tela, l’SVG lavora in XML e ogni oggetto diviene un elemento del DOM a se stante. Questo si traduce in due modi diversi di disegno: Canvas disegnerà in immediate mode, mentre SVG in retained mode. 29
  • 36. Il modo immediato è pixel oriented ossia, il meccanismo di disegno non tiene traccia delle forme disegnate e il browser disegnerà semplicemente i pixel della tela. Se vi sono due oggetti sovrapposti si preoccuperà semplicemente di disegnare quello sovrapposto e non vi sarà traccia di quello sottostante. Questo porta a delle prestazioni più elevate, soprattutto nel caso in cui bi- sogna ridisegnare più oggetti [13], ma delega allo sviluppatore il compito di tenere eventualmente conto delle forme e dare dunque un significato logico al disegno. Il modo memorizzato invece risulta essere shape oriented, ovvero per ogni forma il browser allocherà una porzione di memoria che verrà singolarmente passata al API grafica, per creare una bitmap corrispondente. L’appesanti- re la memoria relativa al DOM e la molteplicità delle chiamate API, rende l’SVG mediamente meno performante, rispetto al Canvas, ma in compenso si ha nativamente il controllo su ogni singolo elemento disegnato. Fortu- natamente esistono librerie canvas che implementano questo controllo sugli oggetti disegnati, senza però sacrificare drammaticamente le prestazioni del Canvas. 2.1.1 FabricJs FabricJs è una libreria canvas, che punta a semplificare le API Canvas native e uniformarle al paradigma della programmazione ad oggetti. A differen- za di quest’ultime infatti, che operano sul contesto (ossia un oggetto che rappresenta tutta la tela bitmap), FabricJs opera sui singoli oggetti disegna- ti, permettendoci di stabilire una corrispondenza di ereditarietà tra di essi. FabricJs si occuperà inoltre della gestione di memoria del canvas e del rende- ring degli oggetti. Questo viene ottenuto trasparentemente, instanziando più canvas e formando cosı̀ degli strati, in modo da poter tenere fisso un livello, come ad esempio lo sfondo, variando contemporaneamente i livelli superiori, che permette di implementare un sistema di caching e risparmiare risorse di computazione, soprattutto nel caso delle animazioni, ottenute variando le proprietà degli oggetti nei vari frame renderizzati sequenzialmente. Con una sintassi che rassomiglia le librerie Javascript per la manipolazione del DOM come ad esempio jQuery, è possibile associare ad ogni oggetto un certo comportamento in risposta ad un evento ben definito. FabricJs è disponibile anche a lato server, il che lo rende un ottimo candidato per la variazione implementativa che verrà discussa nelle Conclusioni [4]. FabricJs si aggancerà ad un elemento di tipo <canvas>, definito nel file html di base. Quando la pagina verrà caricata si inizializzerà la tela, che raffigurerà nel nostro caso, il campo da gioco. In particolare verrà richiamata la funzione: 30
  • 37. function init() { const canvas = new fabric.Canvas("canvas", config.canvas); const circles = Array(config.players) .fill({}) .map(() => new fabric.Circle(config.circle)); fabric.Image.fromURL(config.urlImage, (img) => { canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), { scaleX: canvas.width / img.width, scaleY: canvas.height / img.height, backgroundImageStretch: false, hoverCursor: "pointer", backgroundColor: null, }); }); circles.forEach((circle, index) => { if (index >= 5) { circle.fill = "blue"; } circle.top = initialPositions.players.at(index).top; circle.left = initialPositions.players.at(index).left; canvas.add(circle); }); } La funzione disegnerà la tela ed un segnaposto, in questo caso cerchi, per ogni giocatore. Un’immagine del campo da gioco, la cui risoluzione verrà ridimensionata a quella del canvas verrà posta come sfondo e ogni giocatore riceverà una colorazione in base alla squadra appartenente e verrà posto nella posizione iniziale ricoperta dal suo ruolo. Dopo aver invocato la funzione la tela si presenterà come in Figura 2.1 Alternativamente, il canvas potrebbe essere inizializzato usando l’oggetto StaticCanvas. Questa variante non dà la possibilità all’utente di interagire con il canvas in futuro, ma alleggerisce il carico computazionale. In que- sto modo ogni miglioria basata sull’iterazione, come ad esempio il mostrare le informazioni di un certo giocatore cliccando sopra al relativo segnapo- sto, verrebbe troncata, ma in compenso il sistema potrebbe dimostrarsi più reattivo. Nel confronto con la prossima libreria verrà presa in considerazio- 31
  • 38. ne l’implementazione che si dimostrerà migliore secondo gli indici definiti in seguito. Figura 2.1: Canvas inizializzato Ad ogni messaggio contenente le posizioni aggiornate, si disegnerà un nuovo frame: function drawOnCanvas(newPositions) { circles.forEach((circle, index) => { circle.top = newPositions.at(index).top; circle.left = newPositions.at(index).left; } canvas.renderAll(); } Data l’alta frequenza di aggiornamento non verrà richiesta alcuna anima- zione tra un frame e l’altro. 2.1.2 KonvaJs KonvaJs è un’altra libreria Canvas popolare, specializzata anch’essa nella grafica bidimensionale. L’elemento che farà da ancora nel file html princi- pale in questo caso sarà un <div> sul quale verrà instanziato uno Stage. 32
  • 39. Ogni Stage conterrà a sua volta uno o più Layer, sui quali verranno dise- gnate le varie forme. I layer sono implementati con l’ausilio di due elementi <canvas>, il primo che ha il compito di renderizzare la scene, mentre il secondo è ottimizzato per rilevare gli eventi relativi alle forme sulla tela. A differenza di FabricJs quindi KonvaJs offre allo sviluppatore una granu- larità di configurazione più fine. Nel nostro caso la funzione di inizializzazione si traduce in: function init() { const stage = new Konva.Stage(config.canvas); const layer = new Konva.Layer(); const background = new Konva.Layer(); stage.add(background); stage.add(layer); const circles = Array(config.players) .fill({}) .map(() => new Konva.Circle(config.circle)); Konva.Image.fromURL(config.urlImage, (img) => { img.setAttrs({ scaleX: stage.width() / img.width(), scaleY: stage.height() / img.height(), }); background.add(img); background.draw(); }); circles.forEach((circle, index) => { if (index >= 5) { circle.fill("blue"); } circle.position(initialPositions[index]); layer.add(circle); }); layer.draw(); } che produrrà lo stesso risultato ottenuto anche in precedenza e visibile in 33
  • 40. Figura 2.1. Analogamente a prima, alla ricezione delle nuove posizioni seguirà l’aggiornamento della tela: function drawOnCanvas(newPositions) { circles.forEach((circle, index) => { circle.position({ x: newPositions.at(index).x, y: newPositions.at(index).y }); } layer.draw(); } 34
  • 41. 2.2 Confronto Il confronto FabricJs e KonvaJs è stato effettuato con l’ausilio del tool di misurazione di prestazioni di Chrome, registrando i tempi di tutti i passi relativi alla ricezione e alla visualizzazione dei dati durante una diretta dal vivo. Dalle misurazioni delle prestazioni, in un finestra temporale di 5 minuti, si sono ricavati i seguenti risultati: Idle Scripting Rendering Painting System 90.12% 3.39% 2.11% 2.07% 2.31% 89.03% 4.14% 2.16% 2.32% 2.34% KonvaJs FabricJs Figura 2.2: Suddivisione delle fasi per la visualizzazione dei dati Come si può notare dal diagramma in Figura [2.2], il sistema a front-end passa la maggior parte del tempo in stallo. I tempi di renderizzazione e di- segno dei dati risultano infinitesimi in ambedue i casi ed entrambe le librerie sono quindi soddisfacenti. Le prestazioni sono quasi del tutto coincidenti, il che sta ad indicare che entrambe le librerie al di sotto utilizzano , le stes- se API Canvas HTML5 e che le tecniche di caching, nelle quali potrebbero differenziarsi, non sono influenti per le dimensioni dei dati in questione. Te- nendo in considerazione la qualità della documentazione in rete e la facilità di sviluppo, si è scelto di utilizzare FabricJs. 35
  • 42. Capitolo 3 Implementazione prototipo L’obbiettivo principale di questo capitolo è quello di mettere in pratica quan- to appreso fin’ora emulando un riproduttore dello streaming, prendendo come punto di riferimento il riproduttore live della nota piattaforma di YouTube. La rappresentazione verrà realizzata utilizzando FabricJs e WebSocket, le due tecnologie scelte precedentemente. Inizialmente verrà illustrata l’interfaccia per poi addentrarsi nella realizzazione. Oltre alla mera rappresentazione dei dati infatti, bisognerà realizzare anche un sistema di gestione del flusso, con- trollabile dallo spettatore. A tal scopo verrà introdotta una nuovo tipo di architettura del software, quella guidata ad eventi, che permetterà di risolve- re i problemi di concorrenzialità e scalabilità. In fine verranno discussi alcuni accorgimenti e migliorie che potrebbero rendere il sistema più robusto, indi- pendente dai protocolli sottostanti e giovare quindi all’esperienza utente in generale. 36
  • 43. 3.1 Client Per implementazione del player si intende la codifica da parte del client, dei comandi che controllano il flusso di dati e l’atteggiamento che deve assumere il server dopo aver ricevuto tali comandi. Si discuterà ora la prima e in seguito la seconda. A livello client si hanno due file principali: index.html, che determina la struttura del documento e index.js, che ne implementa la logica di funzio- namento ed il file config.js, che per comodità ragrupperà tutti i parametri di configurazione. Il file HTML oltre ad importare i vari fogli di stile come Bootstrap e gli script relativi alla libreria canvas che verrà utilizzata, defini- sce anche i quattro pulsanti che verranno utilizzati per gestire il flusso e che verranno posti sotto la tela canvas che animerà le posizioni. Questi sono rela- tivamente: il pulsante play che ordinerà al server di mandare i dati a partire da una certo frame temporale, il pulsante range che servirà a scegliere questo frame e che verrà aggiornato ad ogni ricezione di dati, il pulsante pause che fermerà la ricezione ordinando al server di mettersi in stallo ed il pulsante live, che farà si che il client riceva i dati più aggiornati indipendentemente dal frame corrente. Figura 3.1: Comandi player per la gestione del flusso Lo script principale, si occuperà di definire il funzionamento di questi pulsanti, le relazioni tra di essi e di gestire i dati in entrata. Dopo aver definito i riferimenti al pulsanti si occuperà di aprire la connessione bidirezionale, in questo caso WebSocket, con il server. La connessione avrà delle direttive, in particolare: const ws = new WebSocket(‘ws://localhost:${config.PORT}‘); if (ws) { ws.onopen = () => { playButton.disabled = false; liveButton.disabled = false; pauseButton.disabled = true; rangeButton.value = 0; }; 37
  • 44. ws.onmessage = (message) => { message = JSON.parse(message.data); updateRange(message.frame, message.max); drawOnCanvas(message.positions); }; } A connessione instaurata porterà il frame di riferimento a zero e abiliterà i pulsanti per far partire lo streaming. Quando riceverà un messaggio si occuperà di aggiornare la barra del range e la posizione del puntatore e di disegnare i giocatori sul campo secondo le posizioni ricevute. I pulsanti, una volta cliccati, manderanno alla torretta server degli ordini e si disabiliteranno: playButton.onclick = () => { ws.send(JSON.stringify({ frame: rangeButton.value, type: "play" })); playButton.disabled = true; liveButton.disabled = false; pauseButton.disabled = false; }; liveButton.onclick = () => { ws.send(JSON.stringify({ type: "live" })); playButton.disabled = true; liveButton.disabled = true; pauseButton.disabled = false; }; pauseButton.onclick = () => { ws.send(JSON.stringify({ frame: rangeButton.value, type: "pause" })); pauseButton.disabled = true; playButton.disabled = false; liveButton.disabled = false; liveButton.style.color = ""; }; rangeButton.oninput = (e) => { liveButton.style.color = e.target.value === rangeButton.max ? "red" : ""; liveButton.disabled = e.target.value === rangeButton.max; }; 38
  • 45. rangeButton.onchange = (e) => { ws.send( JSON.stringify({ frame: e.target.value, type: "jump", live: e.target.value === rangeButton.max, }) ); }; Il pulsante di range reagirà inoltre ogni qualvolta la posizione del range subirà un cambiamento, ovvero se ci sarà un input. In questo caso controllerà se si è a fine corsa del range e in questo caso colorerà il pulsante live in rosso e lo disabiliterà, stando a indicare che si sta seguendo lo streaming in diretta. Nel qual caso fosse l’utente a cambiare frame, allora oltre all’input verrà innescato anche l’evento change, che si attiverà quando lo slider verrà rilasciato e che notificherà al server di riavvolgere lo streaming dal frame indicato oppure se il frame è l’ultimo, di mandare i dati più aggiornati. Figura 3.2: Comandi player durante la visione in diretta Di default gli eventi relativi al pulsante di range, sia l’input che il change, non vengono innescati quando il puntatore del range viene modificato per via programmatica, ma solo quando viene fatto esplicitamente dall’utente. function updateRange(value, max) { rangeButton.max = max; rangeButton.value = value; rangeButton.dispatchEvent(new Event("input")); } Per ovviare a questo problema, durante l’aggiornamento della barra di scorrimento, viene innescato manualmente l’evento di input, simulando il cambio da parte dell’utente. Lo stesso paradigma degli eventi verrà usato, anche se per motivi diversi, nella parte server. 39
  • 46. 3.2 Server Il server deve ricevere i dati aggiornati, memorizzarli ed eventualmente fornire all’utente i dati richiesti. Concettualmente questo corrisponde a due cicli: uno che segue i risvolti della partita e che è indipendente dal fatto che un utente sia connesso o meno e un altro che manda i dati ad eventuali utenti connessi. Idealmente si vorrebbe un certo ordine sincronizzato tra i due, ossia ad ogni aggiornamento seguirebbe il mandare dei dati. Definendo due cicli indipendenti, anche se con lo stesso clock, il sincronismo non sarebbe garantito e lo sfasamento tra i cicli sarebbe aggravato dalle tempistiche dei comandi da parte dell’utente. Bisogna quindi comprimere il tutto ad un unico ciclo. Inizialmente si potrebbe pensare di condensare il tutto nel ciclo principale di aggiornamento e valutare l’invio di dati con un costrutto di tipo if-else sulla una variabile rappresentante la connessione. Tuttavia in questo modo la variabile in questione potrebbe rappresentare un’unica connessione, poiché non sarebbe possibile mappare la diramazione nel flusso principale e più client potrebbero influenzare a vicenda il proprio flusso di dati. Occorre allora seguire una struttura denominata Event-Driven Architecture. Figura 3.3: A sinistra un’architettura tradizionale, a destra un’architettura di tipo Event-Driven Un’architettura guidata ad eventi è un architettura software ed un mo- dello di design per applicazioni, concepito per evitare fenomeni di collisione 40
  • 47. tra i componenti applicativi e ridurre la complessità di sincronizzazione. A differenza dei tradizionali modelli richiesta-risposta, la comunicazione tra i vari attori, realizzata attraverso gli eventi, è parte integrante del sistema. Nel nostro caso, come schematizzato in Figura [3.3] al posto di cercare di orchestrare con un puntatore le ramificazioni, date dagli utenti connessi, dal flusso principale, si delega la responsabilità alle ramificazioni stesse. Ad ogni ciclo di aggiornamento dati nel flusso principale verrà innescata una notifica di update, che si dilagherà ad ogni connessione esistente. La singola connes- sione riceverà, a connessione instaurata, le direttive su come comportarsi in caso di ricezione della notifica update. Nel caso di assenza di spettatori, le notifiche resteranno vacanti, mentre se esiste una connessione, essa deciderà in modo indipendente dal ciclo principale, se inviare i dati o meno, a secon- da degli ordini impartiti precedentemente dall’utente. In termini di codice questo si traduce in: setInterval(() => { getNewPositions(); eventEmitter.emit("update"); }, config.BIT_RATE); ... dal flusso principale, mentre per le ramificazioni si ha: ... const wss = new WebSocketServer({ port: config.PORT }); console.log(‘Server is running on port ${config.PORT}‘); wss.on("connection", (ws) => { console.log("New client has connected"); ws.state = "pause"; eventEmitter.on("update", () => { switch (ws.state) { case "live": data = JSON.stringify({ frame: userFrame, positions: history[userFrame], max: history.length - 1, }); ws.send(data); userFrame = history.length; 41
  • 48. break; case "play": data = JSON.stringify({ frame: userFrame, positions: history[userFrame], max: history.length - 1, ws.send(data); userFrame++; break; case "pause": break; } }); ... dove ws.state è lo stato della connessione, impostato dall’utente tramite i controlli descritti precedentemente, mentre history rappresenta la strut- tura dati che memorizza le posizioni relative ai frame precedenti. In una release definitiva, questa struttura dati potrebbe essere data da un’istanza di database. Lo studio delle prestazioni di un database esula dallo scopo di questa tesi e sebbene la scrittura e la lettura dei dati hanno tempisti- che diverse, si può ipotizzare che questi tempi siano trascurabili rispetto al config.BIT_RATE, che assume un valore che si aggira sulla trentina di mil- lisecondi. Nel prototipo quindi è stato usato un semplice array, che viene incrementato ad ogni chiamata di getNewPositions(). In questo caso an- che la diretta verrà visualizzata mostrando i dati, che sono stati memorizzati per ultimi. Lo userFrame rappresenta il frame corrente e coincide, a livello client, con il puntatore sulla barra di riproduzione. Viene incrementato ad ogni invio di dati, assicurandosi inoltre, se siamo in diretta, che coincida con la lunghezza dell’array memorizzato e che al prossimo ciclo prenderà gli ultimi dati. Se si è in pausa il contatore viene congelato e i dati non vengono spediti. In questo caso la barra di riproduzione rimarrà obsoleta per tutto il tempo che il flusso è in pausa perché non riceverà i dati sul frame massimo. Riprendendo il flusso dopo una pausa si avrà un riassestamento del range della barra e di conseguenza della posizione relativa al range del puntatore. Per ovviare a ciò bisognerebbe continuare ad aggiornare il massimo anche quando si è in pausa ma ciò corrisponderebbe visivamente ad un puntatore che scorre all’indietro. Si è notato che anche le dirette su YouTube hanno lo stesso problema di 42
  • 49. riassestamento dopo una pausa e analogamente ad esse si è scelto di seguire la prima strada, essendo il sistema pensato soprattutto per la diretta con al più pause di breve durata. Come visto precedentemente lo spettatore gestisce il flusso con i pulsanti di controllo che a livello di server modificano lo stato della visione e impostano in caso il frame da cui far partire la riproduzione: ... ws.on("message", (msg) => { msg = JSON.parse(msg); switch (msg.type) { case "live": ws.state = "live"; userFrame = history.length - 1; break; case "play": ws.state = "play"; userFrame = msg.frame; break; case "jump": userFrame = msg.frame; if (ws.state !== "pause") { if (msg.live) { ws.state = "live"; } else { ws.state = "play"; } } break; case "pause": ws.state = "pause"; userFrame = msg.frame; break; } }); tra i quali quello più articolato risulta essere il comando di salto, modifica del puntatore nella barra di riproduzione. Se il sistema non è in pausa infatti 43
  • 50. bisognerà verificare se il puntatore è stato trascinato alla fine della barra, il che si traduce nella richiesta di una diretta o di una normale riproduzione negli altri casi. La riproduzione dei dati, sia di quelli precedenti, che di quelli correnti sarà ricevuta dal client, che si occuperà di rappresentarla attraverso tecnologia canvas. 44
  • 51. 3.3 Migliorie Ogni sistema di trasmissione e visualizzazione dati, soprattutto in ambito multimediale, implementa degli accorgimenti a front-end, che rendono più fluida l’esperienza visiva e mitigano i danni causati dai possibili ritardi e per- dite di dati. La tecnica più diffusa per fare ciò, è quella del buffering, che consiste nell’introdurre una struttura dati, denominata buffer, che conterrà alcuni campioni passati e futuri rispetto ai dati visualizzati. L’utente potrà in questo modo variare localmente la riproduzione, senza dover interagire con il server e se la cadenza di ricezione dei dati è maggiore rispetto a quella di visualizzazione, allora il sistema avrà modo di stabilizzare la connessione in caso di turbolenze di comunicazione, senza che l’utente se ne accorga. Nel nostro caso è possibile introdurre due stati del sistema ed un semplice ar- ray di lunghezza pari: se il sistema è nello stato play, allora l’array verrà riempito con metà campioni passati e metà futuri, mentre se è nello stato live si riempirà l’array con soli campioni passati. Tuttavia nel nostro caso la visualizzazione dei dati segue immediatamente la ricezione e non si avreb- bero tutti i benefici di stabilità descritti precedentemente se non quello di risparmiare sulle iterazioni con il server. Si può tuttavia emulare il compor- tamento del buffering in condizioni di rete non ottimali, dal punto di vista dello spettatore, per rendere il sistema più robusto. Figura 3.4: Schermata di caricamento dei nuovi dati 45
  • 52. Il nostro sistema infatti, cosı̀ com’è stato concepito, non prevede dati non ordinati oppure perdite dei dati da parte del sistema di comunicazioni e non permette quindi, di sostituire il protocollo sottostante del WebSocket, con uno più permissivo in termini di affidabilità, come quello del WebRTC. Banalmente, con perdite di dati si avrebbe un riproduzione a singhiozzo, mentre con dati non ordinati una riproduzione caotica. Per far fronte a ciò si potrebbe pensare di introdurre la schermata di caricamento in Figura [3.4], comunemente nota come schermata di buffering, che segnali all’utente la scarsità delle risorse di rete e che duri fino alla ricezione dei nuovi dati. Il funzionamento di base sarà simile a quello del timer di acknowledgemnt del TCP: quando il front-end riceverà un messaggio da parte della torretta server, allora reinizializzerà il contatore, se esistente, rimuoverà la schermata di caricamento, se presente. Se un dato non verrà ricevuto in tempo, il contatore raggiungerà il fine corsa e mostrerà la schermata di caricamento. La lunghezza del contatore dovrà quindi essere configurata in modo adeguato per dare tempo ai dati di raggiungere il front-end. Nel caso di cadenza di ricezione dei dati regolare, non si avranno interruzioni, tuttavia non appena uno o più dati tarderanno ad arrivare l’utente ne verrà a conoscenza. La schermata di caricamento verrà implementata da due funzioni: function buffering(time) { clearTimeout(timer); canvas.remove(icon); blur(false); timer = setTimeout(() => { blur(true); fabric.Image.fromURL(config.urlBufferingIcon, (img) => { img.scale(0.2); img.originX = "center"; img.originY = "center"; canvas.add(img); canvas.centerObject(img); icon = img; setInterval( () => img.animate("angle", "+=20", { duration: 50, onChange: canvas.renderAll.bind(canvas) }), 50 46
  • 53. ); }); }, time); } la funzione base si occuperà di implementare la logica di base e gestire l’animazione di rotazione dell’icona di caricamento centrale che nel nostro caso è una circonferenza tagliata, mentre la funzione di sfocatura si occuperà di applicare i relativi filtri al canvas: function blur(active) { canvas.backgroundImage.filters.pop(); const filter = active ? new fabric.Image.filters.Blur({blur: 0.1}) : null; canvas.backgroundImage.filters.push(filter); canvas.backgroundImage.applyFilters(); canvas.getObjects().forEach((object) => { object.visible = !active; }); } Con l’introduzione della schermata di caricamento, si è risolto il problema della mancata ricezione dei dati ma resta il problema dell’ordinamento. Per rendere il font-end indipendente da ciò, si potrebbe pensare di visualizzare un dato, solo se l’identificativo numerico del dato è maggiore o uguale al valore del puntatore del range della barra di riproduzione. Dato che quest’ultimo è sincronizzato con i dati del server, allora i dati passati, non espressamente richiesti dall’utente, non verrebbero visualizzati. Facendo partire il timer alla visualizzazione e combinando quindi la scher- mata di caricamento, con il vincolo di visualizzazione dei dati, si rende il sistema indipendente dal protocollo di trasmissione sottostante. 47
  • 54. Capitolo 4 Conclusioni L’obbiettivo dell’analisi e della prototipazione del sistema di streaming in diretta è stato raggiunto. Restano tuttavia da fare alcune considerazioni finali sull’implementazione, la struttura dell’applicazione e sulle cose apprese da questa tesi. Come si è visto nel confronto della sezione 1.4 non vi è una sostanziale differenza tra la latenza che si ottiene utilizzando WebRTC e quella che si ha con WebSocket. Cio è è da attribuirsi alle dimensioni dei dati transitanti del- l’applicazione. Tuttavia utilizzando le API di WebSocket si ha la possibilità di differenziare la risorsa rappresentante la diretta di una partita, direttamen- te con l’URL senza doverlo fare per via programmatica. Utilizzando inoltre un framework di applicazioni web che integra la gestione WebSocket, come ad esempio express-ws, si potrebbe estendere elegantemente l’applicazione ad un sito web, che ospita più incontri in diretta, ognuno con il proprio player incapsulato come componente. Dato che, come osservato nella sezione 2.2, il carico di visualizzazione dei dati sul canvas risulta minimo e che le risorse utilizzate per eseguire questa operazione sono trascurabili, si potrebbe pensare di spostare il tutto a lato server. Le librerie come FabricJS sono infatti supportate nativamente nel- l’ambiente NodeJs e i fotogrammi del campo da gioco verrebbero scattati direttamente dal server, per poi essere spediti al client. In questa ottica, la scelta di WebRTC risulterebbe più sensata dato che verrebbe utilizzato il ca- nale dedicato e ottimizzato per la trasmissione di flussi multimediali, mentre il canale dei dati arbitrari si potrebbe utilizzare per la gestione del flusso da parte del client, oppure per creare una bacheca di commenti condivisa dagli spettatori, similmente a come accade nelle dirette di Youtube. Mandando inoltre i dati con un flusso multimediale, non si avrebbe la necessità, a livello di client, di creare a mano il player, dato che si potrebbe utilizzare diretta- 48
  • 55. mente l’elemento <video> introdotto da HTML5, oppure librerie Javascript più raffinate come Video.Js. Utilizzare pezzi di codice già consolidati dalla comunità dovrebbe sperabilmente portare a meno bug e di norma dovrebbe essere la corsia preferenziale. Durante lo svolgimento della tesi ho avuto modo di imbattermi in pro- tocolli di comunicazione e tecnologie lato frontend a me prima sconosciuti. Analizzando l’implementazione dei primi ho preso dimestichezza con le do- cumentazioni RFC e ho avuto modo di imbattermi in concetti nuovi, relativi alle reti di calcolatori, come ad esempio il peer-to-peer e di ampliare quelli appresi precedentemente durante la mia carriera universitaria, come il NAT. A lato frontend ho avuto modo di prendere dimestichezza con gli strumenti di sviluppo del browser e di implementare un’ architettura guidata ad eventi. Ho consolidato inoltre la mia conoscenza del linguaggio Javascript, in parti- colare ES6, anche per la gestione della parte backend, con l’ausilio di NodeJs, integrato con librerie aggiuntive. In definitiva mi considero soddisfatto dello svolgimento della tesi. 49
  • 56. Bibliografia [1] D. Skvorc, M. Horvat, and S. Srbljic. Performance evaluation of web- socket protocol for implementation of full-duplex web streams. IEEE Internet Computing, pages 1003—-1008, May 2014. [2] Victoria Pimentel and Bradford G. Nickerson. Communicating and displaying real-time data with websocket. IEEE Internet Computing, 16(4):45–53, May 2012. [3] G. Camarillo. Peer-to-peer (p2p) architecture: Definition, taxonomies, examples, and applicability. RFC 5694, RFC Editor, November 2009. https://www.rfc-editor.org/rfc/rfc5694. [4] Pyda Srisuresh and Matt Holdrege. Ip network address translator (nat) terminology and considerations. RFC 2663, RFC Editor, August 1999. http://www.rfc-editor.org/rfc/rfc2663. [5] R. Stewart. Stream control transmission protocol. RFC 4960, RFC Editor, September 2007. http://www.rfc-editor.org/rfc/rfc4960. [6] Jim Fisher. How does reliability work in data channel? https://jameshfisher.com/2017/01/17/ webrtc-datachannel-reliability/. [7] Oracle Documentation. Stream control transfer protocol over- view. docs.oracle.com/en/industries/communications/ enterprise-session-border-controller/8.3.0/configuration/ stream-control-transfer-protocol-overview.html. [8] Berat Yilmaz, Ertugrul Barak, and Suat Ozdemir. Improving webrtc security via blockchain based smart contracts. IEEE, December 2020. [9] Al-Fannah Nasser Mohammed. One leak will sink a ship: Webrtc ip address leaks. In 2017 International Carnahan Conference on Security Technology (ICCST), pages 1–5, 2017. 50
  • 57. [10] Ben Feher, Lior Sidi, Asaf Shabtai, Rami Puzis, and Leonardas Maro- zas. Webrtc security measures and weaknesses. International Journal of Internet Technology and Secured Transactions, 8(1):78–102, May 2018. [11] Rasmus Eskola and Jukka K Nurminen. Performance evaluation of we- brtc data channels. In Symposium on Computers and Communication, pages 676–680. IEEE Computer Society Conference Publishing Services, 2015. [12] Arto Heikkinen, Timo Koskela, and Mika Ylianttila. Performance eva- luation of distributed data delivery on mobile devices using webrtc. In 2015 International Wireless Communications and Mobile Computing Conference (IWCMC), pages 1036–1042, 2015. [13] Boris Smus. Performance of canvas versus svg. https://smus.com/ canvas-vs-svg-performance/ (2009/01/19). [14] Hector Stenger. Utilizing webrtc datachannels in a server-to-peer connection. Master’s thesis, University of Amsterdam, 2018. [15] Dan Ristic. Learning WebRTC. Packt Publishing, 2015. [16] Andreas Reiter and Alexander Marsalek. Webrtc: Your privacy is at risk. In Proceedings of the Symposium on Applied Computing, pages 664–669. Association of Computing Machinery, 2017. [17] I. Fette and A. Melnikov. The websocket protocol. RFC 6455, RFC Editor, December 2011. https://www.rfc-editor.org/rfc/rfc6455. [18] R. Jesup, S. Loreto, and M. Tüxen. Webrtc data channels. RFC 8831, RFC Editor, January 2021. https://www.rfc-editor.org/rfc/ rfc8831. [19] M. Petit-Huguenin, G. Salgueiro, J. Rosenberg, D. Wing, R. Mahy, and P. Matthews. Session traversal utilities for nat (stun). RFC 8489, RFC Editor, February 2020. http://www.rfc-editor.org/rfc/rfc8489. [20] J. Rosenberg. Interactive connectivity establishment (ice): A protocol for network address translator (nat) traversal for offer/answer protocols. RFC 5245, RFC Editor, April 2010. http://www.rfc-editor.org/ rfc/rfc5245. [21] H. Alvestrand. Transports for webrtc. RFC 8835, RFC Editor, January 2021. http://www.rfc-editor.org/rfc/rfc8835. 51
  • 58. [22] C. Holmberg, S. Hakansson, and G. Eriksson. Web real-time communi- cation use cases and requirements. RFC 7478, RFC Editor, March 2015. http://www.rfc-editor.org/rfc/rfc7478. [23] Henrik Boström Cullen Jennings and Jan-Ivar Bruaroey. Webrtc 1.0: Real-time communication between browsers. https://www.w3.org/TR/ webrtc/ (2020/10/20). [24] NTT Communications. A study of webrtc security. https:// webrtc-security.github.io/. [25] Tim Steeves. Webrtc nat traversal methods: A case for embedded turn. https://www.liveswitch.io/blog/ webrtc-nat-traversal-methods-a-case-for-embedded-turn(2022/03/13). [26] Peter Thatcher. Multi-device calls with ice forking. https://signal. org/blog/ice-forking/ (2021/01/26). [27] E. Ivov, J. Uberti, and P. Saint-Andre. Trickle ice: Incremental provisioning of candidates for the interactive connectivity establish- ment (ice) protocol. RFC 8838, RFC Editor, January 2021. http: //www.rfc-editor.org/rfc/rfc8838. [28] Michael Welzl. Network Congestion Control: Managing Internet Traffic. John Wiley & Sons, 2005. [29] MDN Contributors. Evolution of http. https://developer. mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_ of_HTTP(2022/05/13). [30] Alessandro Ghedini. The road to quic. https://blog.cloudflare. com/the-road-to-quic/(2018/07/28). [31] Jeff Posnick. Using webtransport. https://web.dev/ webtransport/(2022/01/22). [32] RedHat Blog. What is event-driven architectu- re? https://www.redhat.com/en/topics/integration/ what-is-event-driven-architecture (2019/09/27). [33] Robert Lane. Event-driven programming in node.js. https://www.digitalocean.com/community/tutorials/ nodejs-event-driven-programming (2018/01/11). 52
  • 59. [34] Josh Marinacci. Html canvas deep dive. https://joshondesign.com/ p/books/canvasdeepdive/title.html. [35] Fabricjs. https://fabricjs.com. [36] Konvajs. https://konvajs.org. 53