• Non ci sono risultati.

5.4 Gli aspetti collaborativi della piattaforma

5.4.2 Collaborazione sincrona

5.4.2.1 Modica in tempo reale di una composizione

Il punto cruciale della collaborazione sincrona è l'interazione in tempo reale tra due utenti che lavorano modicando lo stesso oggetto. Naturalmente perché ciò avvenga gli utenti coinvolti devono avere la sensazione di essere nello stesso ambiente e di osservare lo stesso oggetto degli altri, con lo scenario che si modica ed evolve in tempo reale, nell'immediatezza di pochi secondi. Solo in questo modo si può dare agli utenti la sensazione di lavorare sul medesimo oggetto in maniera sincrona.

La prima problematica riscontrata è stata come rendere possibile l'aggiorna- mento in tempo reale di una composizione. Abbiamo individuato due soluzioni: una in cui sul server è mantenuta una copia dello schema della composizione, l'altra in cui sul server vi è solo una coda delle azioni intraprese dagli utenti partecipanti alla sessione, e gli schemi delle composizioni sono mantenuti solo sui client.

Nella prima soluzione si deve mantenere sul server una copia dello schema della composizione, e ogni volta che un utente esegue un azione, tale schema si deve aggiornare, e poi dev'essere spedito a tutti gli altri client partecipanti alla sessione, che ricevuto il nuovo schema, devono aggiornare la visualizzazione del mashup con le modiche eseguite. Questo è oltremodo scomodo per l'utente, perché si tratterebbe di ricaricare la composizione, azione che decisamente non è trasparente, visto che richiede un paio di secondi di attesa. Se poi coinvolti nella sessione di lavoro vi siano un suciente numero di utenti che modicano frequen- temente la composizione, si arriva facilmente ad una situazione di inusabilità del mashup. Inoltre una soluzione di questo tipo implica un carico computazionale maggiore da parte del server che, ricevuta un'azione da parte di un client deve applicarla allo schema che ha salvato. Questo potrebbe portare a dei ritardi nelle chiamate al server e alla conseguente instabilità della piattaforma.

Nel secondo caso, come mostrato in gura 5.10, invece si deve mantenere sul server solo una coda di azioni eseguite dagli utenti, e non uno schema completo della composizione, che invece viene mantenuto client-side. Con questo approcco si riduce il carico operazionale sul server, e si invano ai client, non più uno schema completo della composizione da ricaricare, ma una serie di azioni da eseguire sulla copia locale dello schema, così da aggiornare la composizione vista dal client. Questa operazione è completamente trasparente all'utente, grazie all'utilizzo delle funzioni che vengono normalmente richiamate dall'interfaccia graca per agire sulla composizione. In questo modo l'utente vedrà modicare la composizione,

5.4 Gli aspetti collaborativi della piattaforma 93 Client1 Client2 Server JSON Action JSON Action DATABASE JSONJSON JSON Action addActions() propagateActions()

Figura 5.10: Schema della propagazione delle azioni e coda azioni sul database come se fosse lui stesso ad aver apportato quelle modiche, dando la sensazione all'utente di essere faccia a faccia con i suoi collaboratori a lavorare sulla stessa istanza della composizione.

5.4.2.1.1 La nostra implementazione La soluzione adottata si basa sul si- stema dell'Ajax Polling (si veda il Capitolo 3), principalmente per una questione di compatibilità e semplicità nel controllo di alcuni parametri come la frequenza di aggiornamento dell'interfaccia. Per gli aspetti negativi di tale tecnica, siamo riusciti a trovare un equilibrio tra timeout e ritardo della rete abbastanza soddi- sfacente, anche se riconosciamo che questo è uno degli aspetti critici della nostra applicazione, e che non appena il supporto a certe tecnologie, come Node.js, sarà più diuso, sarà necessaria l'implementazione di una di esse per garantire solidità all'applcazione.

Come prevede la tecnica dell'Ajax polling, è stata creata sul client, all'inter- no dell'oggetto che gestisce l'interazione in tempo reale, una funzione che viene periodicamente rieseguita. Tale funzione esegue una chiamata Ajax verso una pagina PHP, che controlla se sono state eettuate delle azioni da parte degli altri utenti, che non sono state ancora inviate all'utente che ha fatto la richiesta. In caso aermativo, la chiamata restituisce l'azione che è stata eettuata, in caso negativo non restituisce niente. Nel caso in cui venga restituita un'azione, tale azione, è contenuta in una stringa JSON insieme ai parametri per poter essere eseguita.

Cercando di creare una visione completa dell'interazione e della propagazione delle azioni tra i vari utenti connessi, descriviamo ora un breve scenario (Fi- gura 5.11), in cui un utente esegue un'attività e tale azione si propaga sulla composizione di un altro utente connesso.

Cercando di creare una visione completa dell'interazione e della propagazione delle azioni tra i vari utenti connessi, descriviamo ora un breve scenario in cui un utente esegue un'attività e tale azione si propaga sulla composizione di un altro utente connesso.

Non appena l'utente 1 esegue un'azione, tale azione viene inviata al server (addAction) dopo essere stata inserita in una stringa JSON, in una forma che renda facile e veloce l'esecuzione di tale azione. Non appena il server riceve l'azione, la salva nel database, dove si genera una coda di azioni specica per quella composizione. Attraverso l'Ajax Polling gli altri utenti eseguono delle chiamate periodiche verso il server (checkAction) per sapere se vi sono nuove azioni nella coda, e alla prima chiamata da parte dell'uten- te 2, che giunge dopo l'azione dell'utente 1, il server restituisce a 2 il JSON dell'azione fatta da 1. Naturalmente se 1 avesse fatto più azioni nell'in- tervallo di tempo in cui 2 controlla, 2 avrebbe ricevuto un array ordinato di azioni (ActionList) da eseguire nell'ordine specico in cui le ha ricevute (gura 5.12). Una volta che 2 ha ricevuto il JSON dell'azione eseguita da 1, valuta la stringa, così da estrarne il tipo di azione eettuata e i parametri ad essa connessi, passando il tutto all'oggetto che si occupa di gestire la composizione sul client di 2. L'azione viene poi eseguita come se fosse un'a- zione fatta da 2, perciò l'utente vedrà cambiare il proprio spazio di lavoro (updateView), senza aver fatto alcuna azione, avendo la sensazione di stare osservando la stessa istanza che sta osservando 1.

Una volta realizzato il sistema per l'interazione in tempo reale tra due utenti che operano e modicano una stessa composizione, si è dovuto decidere come far aprire ad un utente una sessione di modica in tempo reale. Abbiamo considerato due scenari: uno in cui tutte le composizioni si aprono normalmente in una sessione di modica non in tempo reale e l'utente, attraverso un apposito menu è in grado di invitare più utenti all'interno della stessa sessione, e una in cui le composizioni, se condivise, si aprono direttamente in una sessione live. Nel primo caso si rende l'utente conscio n da subito della dierenza tra aprire una composizione e aprire una composizione in modalità live, dando la possibilità all'utente di invitare solo chi vuole. Tuttavia un meccanismo di questo tipo rende estremamente complesse alcuni meccanismi di per se semplici, come il salvataggio. Se durante una sessione live, infatti, un utente che non ne fa parte, modica e salva la stessa composizione, si avrebbe un avanzamento di versione, e la composizione che viene modicata all'interno della sessione live non è più aggiornata. Se poi si arrivasse ad una richiesta di salvataggio da parte degli utenti coinvolti nella sessione live come comportarsi? Molto più semplice è il secondo scenario, che

5.4 Gli aspetti collaborativi della piattaforma 95 Client Client user1 Client Server executeQuery

(<action1,comp1>) addAction(<action1, comp1>)

ActionList {<action1, comp1>,...}

user2 updateView()

user3

ActionList

{<action1, comp1>,...} updateView() checkAction() ActionList {...} updateView() checkAction() checkAction() Loop Loop Loop

{ " actions ":[{ "95":{ " actor ":"m", " action ": { " compId ":" component0_contents ", " operation ":" syncStatus ", " action ":" searchByKey ", " arguments ":[ "cat" ] } } }, { "96":{ " actor ":" mik", " action ":{ " compId ":" component3_contents ", " operation ":" removeComponent ", " args ":" Flickr " } } }] }

5.4 Gli aspetti collaborativi della piattaforma 97 porta l'utente ad aprire, automaticamente, una sessione live di modica della composizione, e tutti gli altri utenti che apriranno quella stessa composizione non faranno altro che unirsi alla sessione di modica live avviata dal primo utente. In questo modo non si presentano quelle problematiche del primo scenario, perché tutti gli utenti si trovano a lavorare sulla stessa composizione, e un salvataggio causa l'avanzamento di versione per tutti i partecipanti della sessione live. La problematica di questo approccio è data dal fatto che l'utente non sa quando, all'apertura di una composizione condivisa, è l'unico ad averla aperta o vi sono più utenti che stanno lavorando sulla stessa.

Per rendere l'utente conscio di essere in una sessione live e per capire cosa gli utenti stanno guardando, o modicando, o più semplicemente quanti utenti sono online e chi sono, abbiamo implementato una serie di strumenti a supporto dell'utente:

Utenti Online: permette di monitorare gli utenti presenti all'interno di uno spazio di lavoro condiviso. All'occorrenza è possibile visualizzare i nomi degli utenti online (Figura 5.13), associati ad un colore di riferimento, che caratterizzerà le interazioni di quello specico utente nel workspace. La vera sda però è stata come capire se un utente è online oppure no. Ci sono molti modi per abbandonare una sessione online, alcuni facili da in- tercettare, come l'apertura di un altra composizione, altri impossibili da rilevare, come la chiusura del browser. Per capire se un utente è online ci siamo allora adati ancora dell'Ajax Polling. Infatti se ogni volta che il client fa una chiamata al server, per vericare la presenza di nuove azio- ni, si tiene traccia dell'istante dell'interazione, si può calcolare l'intervallo di tempo in cui l'utente non ha eettuato chiamate al server, e se questo intervallo supera un certo livello di time-out, allora consideriamo l'untente oine e perciò fuori dalla sessione live. Naturalmente questo meccanismo sore delle stesse criticità di cui sore il sistema su cui si basa.

Attività Recenti: permette di visualizzare le azioni eseguite da tutti gli utenti coinvolti nella sessione live, rappresentando uno storico delle azioni che hanno portato allo stato attuale della composizione (Figura 5.14). Queesto meccanismo è particolarmente utile per controllare quelle azioni che non modicano l'aspetto della composizione, ma il suo comportamento.

Highlight: speciale strumento che permette di individuare l'area di azione di ogni specico utente in attività all'interno della Dashboard. Una appo- sita bordatura dei componenti interessati dalla interazione evidenzia, tra- mite l'utilizzo dei colori, quali sono attualmente gli oggetti interessati da modiche e aggiornamenti (Figura 5.13). Ogni client raccoglie e invia le informazioni relative alla posizione del mouse sullo schermo dell'utente, traducendole poi opportunamente in termini di posizione sul componente.

Si è scelto di informare il server degli highlight sfruttando la stessa inter- rogazione, con la quale si richiede l'elenco delle azioni (Figura 5.15): in questo modo è possibile migliorare le performance e ridurre la latenza di interazione con il server, evitando di generare nuovo traco in entrata e in uscita.

Chat: permette di supportare l'interazione durante una sessione live, abilitando la comunicazione tra gli utenti grazie a messaggi di testo. Anche in questo caso i colori richiamano gli utenti online (Figura 5.16).