• Non ci sono risultati.

Capitolo 3 La piattaforma di sviluppo: Macromedia Flash e il Communication Server

N/A
N/A
Protected

Academic year: 2021

Condividi "Capitolo 3 La piattaforma di sviluppo: Macromedia Flash e il Communication Server"

Copied!
15
0
0

Testo completo

(1)

Capitolo 3

La piattaforma di sviluppo: Macromedia Flash e il

Communication Server

Macromedia Flash è una tecnologia che ormai da tempo riscuote successo nella rete ed è molto usata nello sviluppo di siti web. Questa tecnologia si basa sul concetto di filmato o movieClip. Un filmato può contenere grafica, immagini, video, suoni e risulta essere uno strumento perfetto per costruire animazioni visuali. Inoltre è possibile usare componenti UI di base per costruire interfacce grafiche.

Un filmato è formato da una sequenza di fotogrammi – frame – che viene riprodotta dal Flash Player, il plugin di Macromedia per i browser web. Ogni fotogramma è diviso in un certo numero di livelli virtuali su cui possono essere disposte immagini o altri filmati. Il filmato può essere statico, nel senso che tutte le animazioni sono state disegnate frame per frame durante la fase di sviluppo, oppure dinamico cioè il filmato può essere programmato affinché si modifichi a run-time. E’ anche possibile programmare un filmato affinché ascolti gli input dall'utente, come eventi dalla tastiera o dal mouse (e come vedremo anche da altri client attraverso il Communication Server). L'editor di sviluppo Studio 8 di Macromedia Flash è essenzialmente una lavagna su cui disegnare con diversi strumenti grafici e su cui trascinare elementi visuali precostituiti. Questa lavagna mostra correntemente il frame selezionato nella barra del tempo – timeLine – attraverso la quale si scorre il filmato. L'altra faccia dell'editor, è la console di programmazione ActionScript. Nell'impostazione di Studio 8 la console di programmazione rappresenta decisamente un aspetto in secondo piano rispetto agli strumenti per la grafica.

Ogni fotogramma può avere del codice ActionScript associato ad esso per controllare il filmato e per modificarne le proprietà. Ciò significa che ogni frame può essere usato durante la fase di design, come una pagina diversa del sito con i propri oggetti grafici e la propria logica implementata in ActionScipt.

Un documento Flash è quindi un filmato principale detto root, composto da una sequenza di fotogrammi. La pubblicazione di questo documento produce un file di formato SWF ed un template HTML che incapsula un riferimento al file SWF attraverso un tag OBJECT. Il file SWF è il filmato compilato pronto per essere eseguito dal flash Player. Quando il browser scarica e visualizza la pagina HTML, vede il tag object nel quale trova il nome del file SWF da scaricare dal server e il nome del plug-in ossia il Flash Player da usare per visualizzare quel file.

(2)

Figura 1 Un documento flash ha estensione “.fla” . La pubblicazione di questo documento produce un file html e un file swf compilato.

Il filmato root può ordinare al browser di scaricare altri filmati tramite delle chiamate ActionScript. Quindi durante l'esecuzione del filmato possono avvenire più richieste verso il server. E' una buona pratica suddividere, se è possibile un singolo filmato in vari sottofilmati che vengono scaricati solo se è necessario. Ciò permette di aumentare la velocità di visualizzazione dei vari contenuti grafici e di migliorare le prestazioni del sito.

Figura 2 Con la prima richiesta il browser ottiene il file Filmato.html, per il quale scarica successivamente il file Filmato.sw .

(3)

3.1

La programmazione ad oggetti in ActionScript 2.0

Con l'introduzione da parte di Macromedia dell'ActionScript 2.0, è possibile usare la Object Oriented Programming per creare nuove classi. Il tipo base dell’ambiente di sviluppo di Flash è la classe MovieClip. Qualunque entità che viene visualizzata è un MovieClip oppure eredita da esso. Tuttavia, la tecnica più usata per la definizione di nuovi tipi, è quella della programmazione per composizione cioè la definizione di una classe che contiene al suo interno un MovieClip.

La classe quindi incapsula il filmato e lo controlla in base al comportamento definito dalla classe. Ad esempio, un‘ ipotetica classe Box che disegna un quadrato può essere definita in questa maniera:

class Box{

private var width:Number = 100; private var height:Number =100; private var container_mc: MovieClip; public function Box(parent_mc:MovieClip){

container_mc = parent_mc.createEmptyMovieClip(); }

public function Draw():Void{ container_mc.clear(); container_mc.lineStyle(1,0x000000); container_mc.moveTo(0,0); container_mc.beginFill(0xFFFFFF,100); container_mc.lineTo(width,0); container_mc.lineTo(width,height); container_mc.lineTo(0,height); container_mc.lineTo(0,0); container_mc.endFill(); }

public function SetPos(x:Number,y:Number):Void{ container_mc._x = x;

container_mc._y = y; Draw();

} }

In questo esempio, nel costruttore della classe Box , viene creato un nuovo filmato che si chiama container_mc dentro cui verrà disegnato un quadrato nella funzione Draw. Per creare un istanza di questa classe è necessario creare un nuovo documento flash e scrivere in un frame il seguente codice Action Script:

import Box.as;

var b:Box = new Box(this); b.SetPos(100,100);

(4)

Nel codice suddetto, il this è il filmato root del documento Flash. Il codice della classe deve essere contenuto in un file con lo stesso nome della classe e con estensione AS (ActionScript).

Un 'altra possibilità per definire una nuova classe, è quella di usare l'ereditarietà. Supponiamo di voler scrivere una classe Avatar che controlla un oggetto rappresentante lo stato d'animo di un utente in una chat room. Introduciamo quello che nell'ambiente di sviluppo di flash si chiama simbolo della libreria. Un simbolo è un MovieClip che risiede in un area di un documento flash chiamata libreria. Supponiamo quindi di avere nella libreria, un filmato fatto da due frame che contengono rispettivamente un'immagine con una faccina che sorride ed una con una faccina triste. Supponiamo poi di avere la classe Avatar che controlla questo filmato.

class Avatar extends MovieClip{

public static var HAPPY:Number = 1; private static var SAD:Number = 2; public function init():Void{

setState(Avatar.HAPPY); }

public function setState(state:Number):Void{ switch (newState) { case Avatar.HAPPY: this.gotoAndStop(Avatar.HAPPY); break; case Avatar.SAD: this.gotoAndStop(Avatar.SAD); break; } }}

La classe Avatar e il MovieClip con le due immagini vengono associati creando un nuovo simbolo nella libreria. Nel riquadro concatenamento della figura 3, vediamo come si associa il simbolo AvatarSymbol alla classe Avatar. AvatarSymbol è il filmato con le due immagini di cui prima.

(5)

Figura 3 L'interfaccia per legare una classe ad un filmato.

Come si vede dal codice della classe Avatar, non è definito alcun costruttore per questa classe. Infatti l'istanza della classe Avatar può essere creata solo istanziando il simbolo della libreria sulla lavagna di flash, con un drag'n'drop in fase di authoring, oppure invocando il metodo attachMovie.

this.createEmptyMovieClip(“container”):

var av:Avatar = Avatar(container.attachMovie(“AvatarSymbol”,”avatar”,0)); av.init();

Questo codice crea un’istanza grafica del simbolo AvatarSymbol nel filmato root, e allo stesso tempo crea un'istanza, intesa come oggetto, della classe Avatar. Il Flash Player sa che deve costruire l’oggetto di tipo Avatar perché vede che il simbolo AvatarSymbol è associato alla classe Avatar. Quindi ci troviamo in una situazione in cui ci sono due istanze, una grafica e una della classe Avatar legate insieme. La funzione AttachMovie restituisce il tipo MovieClip ma si vuole che l'oggetto av sia di tipo Avatar. Per far ciò è necessario un downcasting che nel codice visto prima viene espresso con la sintassi nomeTipo(oggetto). Un codice più sicuro per il downcasting è il seguente:

var av:Avatar;

var tmp_mc:MovieClip;

this.createEmptyMovieClip(“container”);

tmp_mc = container.attachMovie(“AvatarSymbol”,”avatar”,0); if (tmp_mc istanceOf Avatar){

(6)

av = Avatar(tmp_mc); av.init();

}else{

trace(“Errore di casting..”); }

Definire una classe che eredita dal MovieClip può essere macchinoso, per via del fatto che non si ha a disposizione il costruttore ed è necessario non dimenticare di invocare un metodo (nell'esempio init ) che ne faccia le veci. Questo approccio inoltre, può creare confusione per via della dualità delle istanze, quella grafica e quella della classe.

I componenti

Un terza alternativa a disposizione per creare un oggetto, consiste nel ridefinire gli UIComponent di flash. Questa tecnica permette di semplificare il lavoro a carico del programmatore nei casi in cui è egli debba creare un oggetto che necessita delle funzionalità proprie degli UIComponent. Inoltre permette una più facile gestione della cattura degli eventi provenienti dal mouse e dalla tastiera. Un'altra funzionalità importante che si dispone con i componenti è quella di definire e generare nuovi eventi che possono essere catturati da altri oggetti.

Nella pagina successiva è presente uno schema della gerarchia delle classi di Macromedia Flash. Il tipo base nell’ambiente di sviluppo di Falsh è come abbiamo già detto la classe MovieClip. Da essa, eredita direttamente lo UIObject che definisce la classe base dei componenti UI.

Questo componente non ha nessuno aspetto visuale ma implementa le caratteristiche basilari dei componenti ossia:

• gli stili: ossia dei metodi per impostare l’aspetto grafico del componente • la gestione degli eventi

• la modifica delle dimensioni al cambiamento di scala del componente.

Dallo UIObject eredita UIComponent che aggiunge altre caratteristiche al componente quali la gestione del focus e la attivazione o la disabilitazione del componente.

In base alle necessità, il programmatore sceglie da quale dei due oggetti più basilari, definire il proprio componente

(7)
(8)

La creazione di un nuovo componente avviene definendo una classe in un file AS con lo stesso nome della classe.

import mx.core.UIComponent;

class MyComponent extends UIComponent {

static var symbolName:String = "MyComponent"; static var symbolOwner:Object = MyComponent; var className:String = "MyComponent";

function MyComponent() { }

function init():Void { super.init(); }

private function createChildren(Void):Void { } function draw(Void):Void { super.draw(); } function size(Void):Void { super.size(); invalidate(); }

public function onLoad(Void):Void {

dispatchEvent({type:"myComponentLoaded", target:this}); }

public function myMethod(Void):Void{ trace(“Ciao!”);} }

Nella definizione del componente sono necessari tre campi: symbolName, symbolOwner e className. Questi tre campi servono a preservare lo spazio dei nomi e ad aiutare Flash a risolvere i riferimenti tra i packages e le classi. SymbolName serve a collegare la classe ad un simbolo nella libreria. Di solito il nome coincide con quello della classe. La creazione di un nuovo componente infatti produce un nuovo elemento nella libreria che può essere istanziato attraverso il drag'n'drop sulla lavagna oppure attraverso l'invocazione di createObject, una funzione che usa

SymbolOwner. Quest'ultimo deve coincidere con il nome della classe. Infine className è il nome

della classe che si vuole definire.

createObject("MyComponent","myComponentIstance",0,{_x:0,_y:0});

Il costruttore viene di solito lasciato vuoto e le varie inizializzazioni vengono distribuite tra i metodi init e createChildren. Questi metodi, insieme a draw e size devono essere necessariamente definiti per la corretta costruzione del componente. Essi sono invocati automaticamente dal Flash Player quando l'oggetto viene creato con createObject. In particolare init, viene invocato ossia per primo quando la classe viene istanziata, come se fosse il costruttore. Il metodo invoca a sua volta il metodo init della classe padre che ridefinisce. Il metodo createChildren viene usato per creare istanze di altri componenti che possono essere contenuti da quello che si sta definendo. Esso viene

(9)

invocato subito dopo init. Dopo di che, viene invocato il costruttore che di solito viene lasciato vuoto. Non essendo invocato dal codice, non è possibile passare parametri di inizializzazione al costruttore. Il metodo init fa le veci del costruttore. Il metodo draw serve per modificare gli aspetti visuali del componente. Dentro questo metodo infatti è possibile usare le primitive grafiche di flash (lineTo, beginFill etc) per disegnare linee e forme. Viene invocato la prima volta e quando viene richiesto tramite una chiamata esplicita oppure implicitamente attraverso invalidate. E’ fortemente consigliato invocarlo attraverso il metodo invalidate. In questa maniera, il disegno non viene ridisegnato immediatamente ma lo stato del componente viene salvato in una coda dalla quale il motore grafico del Flash Player ne preleverà il contenuto in un secondo momento. Questo meccanismo permette di migliorare le prestazioni del rendering grafico.

Come abbiamo visto fino ad ora, la creazione di un componente non avviene con una semplice invocazione di un costruttore ma attraverso una serie di chiamate ai metodi predefiniti effettuate dal Flash Player. Ciò genera una situazione alquanto strana e forse inedita per il programmatore: l’invocazione di createObject e la creazione di un nuovo oggetto sono due eventi asincroni! Per questo è assolutamente necessario, usare il classico paradigma del sorgente-ascoltatore, anche per creare un componente. Nell’esempio che abbiamo visto, il metodo onLoad serve proprio a questo, ossia a notificare l’avvenuto caricamento dell’oggetto nel Flash Player. Per caricamento non si intende quello dovuto al download di un altro filmato in quello corrente, ma al processo necessario a visualizzare il componente nel Flash Player. Inoltre, prima che avvenga questo evento, non è possibile riferire l’istanza appena creata con createObject. Il secondo parametro di createObject è infatti inutile per accedere ai metodi dell’oggetto creato. Questo significa che nel codice seguente la prima chiamata a myMethod non avrebbe alcun effetto:

createObject("MyComponent","myComponentIstance",0,{_x:0,_y:0}); myComponentIstance.myMethod();

Solo catturando l’evento myComponentLoaded è possibile ottenere un vero riferimento all’istanza creata. Per ciò, la funzione onLoad, invocata dal Flash Player nel momento in cui esso ha finito di visualizzare il componente, genera un evento attraverso dispatchEvent.

dispatchEvent({type:"myComponentLoaded", target:this});

In questa maniera viene definito un evento che si chiama myComponentLoaded che è un oggetto con due campi: il nome dell’evento e l’oggetto che lo ha generato. L’evento viene definito semplicemente con le parentesi graffe {} dentro cui vengono enumerate i campi type e target. Quest’ultimo è il riferimento all’istanza dell’oggetto che lo ha generato.

3.1.1

La gestione degli eventi

Gli eventi vengono gestiti attraverso il pattern di programmazione sorgente-ascoltatore in cui uno o più listener si mettono in attesa di un evento generato da un broadcaster.

(10)

var myButton:Button;

this.createObject(“Button”,”myButton”,0,{_x:0,_y:0}); // crea un istanza chiamata // myButton

var listener:Object = new Object(); listener.click = function(evt){

trace(evt.target); // evt.target è l’oggetto myButton }

myButton.addEventListener("click", listener);

In questo esempio il broadcaster dell’evento “click” è myButton. Questo oggetto possiede una lista di riferimenti agli oggetti che sono in ascolto di un particolare evento. Quando mybutton genera l’evento click, mybutton scorre la lista degli oggetti in ascolto per l’evento click e per ogni elemento invoca il metodo corrispondente all’evento ( l’evento e il suo gestore hanno lo stesso nome ). Tutti gli oggetti listener implementano quindi una funzione che ha lo stesso nome dell’evento. L’oggetto broadcaster usa il metodo addEventListener per aggiungere un riferimento agli oggetti listener alla sua struttura dati interna.

Tutti i componenti v2 – version 2 – di Macromedia possono generare eventi. Le classi ereditano da UIObject la quale implementa la classe astratta EventDispatcher.

Nell’esempio di pagina 7, l’evento myComponentLoaded può essere catturato in maniera analoga a quanto fatto per il componente predefinito Button.

createObject("MyComponent","myComponentIstance",0,{_x:0,_y:0}); var listener:Object = new Object();

function myComponentLoaded = function(evt){

trace(evt.target); // evt.target è l’oggetto myComponentIstance evt.target.myMethod(); // scrive Ciao!

}

myComponentIstance.addEventListener("myComponentLoaded", listener);

In questo esempio, l’oggetto listener è il filmato root, su un frame del quale abbiamo scritto questo codice. L’esempio appena visto ci fa capire che eventuale altro codice che usa MyComponent dovrà essere contenuto all’interno della funzione myComponentLoaded perché altrimenti non si ha accesso alla vera istanza di MyComponent.

(11)

3.2 Il Flash Communication Server

Il Communication Server viene installato su una macchina come un WebServer ma funziona in maniera diversa. Mentre il WebServer si occupa di servire le richieste di connessione temporanee HTTP, il Communication Server stringe connessioni persistenti con i filmati flash in esecuzione sul Flash Player. Il protocollo usato tra un filmato e il Communication Server si chiama Real Time Messaging Protocol (RTMP). A differenza del protocollo HTTP, il protocollo RTMP stabilisce connessioni persistenti con il server. Una volta accettata la connessione con il filmato client persiste fino all'esplicita richiesta di sconnessione da parte del filmato stesso. Il protocollo RTMP consente di inviare audio codificato in formato mp3 e Nellymoser, video in formato Flash Video Format (FLV), e istruzioni ActionScript in formato Action Message Format (AMF).

Le applicazioni basate sul Flash Communication Server sono composte sul lato server, da uno script Server-Side ActionScript, (SSAS che è molto simile a quello client side). Lo script è contenuto nel file main.asc nella cartella denominata con il nome dell'applicazione. Il filmato flash, risiede su un web Server (che può essere una macchina diversa da quella del CommServer) incapsulato in una pagina html. Ogni computer che usa l'applicazione si connette tramite browser alla pagina html specifica. Il filmato, verrà scaricato e mandato in esecuzione dal Flash Player. Il filmato quindi si connetterà alla macchina del Communication Server tramite una URL che comprende il percorso assoluto della nostra cartella nomeApplicazione oppure il percorso relativo se il filmato e il CommServer risiedono sulla stessa macchina.

Lo scenario tipico di un'applicazione con il Communication Server (nonché quella di Teatrino) è quella mostrata in figura 5 .

Figura 4 Il protocollo HTTP viene usato dai browser per scaricare il filmato Flash che implementa il client. Il protocollo RTMP è usato dai singoli filmati per dialogare tra loro tramite il Communication Server.

Il protocollo RTMP è un protocollo proprietario di Macromedia. Esso si appoggia sul TCP, per trasmettere i pacchetti dal client al server e viceversa. Possiamo immaginare una connessione RTMP come un canale attraverso cui passa audio, video e ActionScript. Questa informazione passa attraverso il Communication Server il quale la smista verso i client. Dato che il protocollo RTMP poggia sul TCP, dentro il canale RTMP ci saranno tante flussi verso il server quanto il numero dei client a cui bisogna consegnare l’informazione. Nel caso di una audio conferenza, se n è il numero

(12)

di client, il server dovrà gestire quindi n connessioni RTMP che poggiano su n quadro connessioni TCP . Ciò è dovuto al fatto che il TCP è un protocollo point-to-point. Quindi ogni client deve inviare l’audio a n client. A differenza quindi dei protocolli di rete per le applicazioni multimediali che fanno uso del multicast e del protocollo UDP, RTMP preferisce inviare dati su un protocollo affidabile e senza perdite. Ciò implica un uso intensivo della banda a disposizione tra il client e il server. Per rendere possibili lo streaming tra più client, RTMP monitora la congestione della rete e decide in base ad essa quale e quanta informazione inviare e quanta scartarne. In base a questa filosofia, i tre tipi di dati inviabili attraverso una connessione RTMP, ossia audio,video e ActionScript sono classificati in ordine d'importanza. Al primo posto c'è l'audio che di solito è l’informazione che rende sostenibile una video conferenza, anche se le immagini non sono scorrevoli. Al secondo posto, ci sono i dati ActionScript. Essi comprendono anche le chiamate a metodi remoti, sul server e sui client. All'ultimo posto, c'è il video considerato meno importante. Audio e video sono accodati nel client, in buffer separati. I buffer si riempiono quando la banda in uscita non riesce a sostenere la banda in entrata. Quando ciò avviene, il buffer audio viene svuotato completamente, mentre quello video viene svuotato solo all'arrivo di un frame chiave. Questo permette in maniera semplice di non inviare frame incompleti, che potrebbero risultare dallo svuotamento del buffer nel momento sbagliato. I dati, cioè le istruzioni ActionScript, vengono sempre inviate. Se non fosse così, le applicazioni potrebbero comportarsi in maniera imprevedibile. Un' applicazione lato server minimale, consiste in una semplice cartella vuota denominata col nome dell'applicazione. Questa cartella contiene gli eventuali SharedObject salvati in file con estensione FSO e gli stream in formato FVL. Al contempo la cartella può contenere file ASC, cioè gli script che vengono eseguiti sul server per gestire le richieste dei client. La figura 5 mostra schematicamente come viene creata un'applicazione sulla piattaforma del Flash Communication Server.

Figura 5

La connessione da parte del client all'applicazione server, avviene tramite l'invocazione del metodo connect. Il Flash Player crea quindi una connessione RTMP al Server. Se nessuna istanza dell'applicazione è già in esecuzione, allora il server invoca il metodo onAppStart. Alla richiesta di connessione da parte di un client, viene invocato sul server onConnect a cui viene passato un nuovo

(13)

oggetto che specifica le caratteristiche del client. OnConnect viene usato solitamente per implementare il codice che decide se accettare o meno la connessione. E' quindi in questo momento che si può ad esempio verificare la password dell'utente oppure controllare se la banda tra il server e quel client è sufficiente per inviare il flusso di dati necessari a quella applicazione. Nella figura 7 è mostrato quanto avviene in questa fase di connessione.

Figura 6 : Diagramma di sequenza che descrive la fase di connessione da parte di un client ad applicazione Flash Communication Server

Il client riceve la risposta dal server con l'invocazione remota, da parte di quest'ultimo, del metodo onStatus. Questo metodo riceve come argomento un oggetto che incapsula l'esito della richiesta di connessione. Quando invece il client si sconnette tramite il metodo close, sul server viene invocato onDisconnect. Se quel client era anche l'ultimo ad essere connesso, allora l'istanza dell'applicazione si ferma con l'invocazione di onAppStop. Tutti i metodi del lato server possono anche non essere implementati. Infatti, come detto prima, per creare una nuova applicazione basta creare sul server una cartella con il nome che si vuole dare all'applicazione. Non deve essere necessariamente presente alcuno script. La cartella verrà comunque usata per contenere gli SharedObject e gli stream salvati sul server.

L'interazione tra i client e il Communication Server avviene tramite due diversi oggetti predefiniti: gli Stream e gli SharedObject. Uno Stream è il flusso di dati multimediali (audio, video) dai client al server e viceversa. Uno stream può essere anche memorizzato sul server nel formato proprietario FLV.

(14)

In Teatrino, gli Stream sono usati dal componente AudioConference per permettere la comunicazione audio tra i client. Gli SharedObject invece, implementano in Teatrino sia la struttura dati condivisa della storia che si vuole recitare, sia la sincronizzazione tra le istanze dei burattini nei vari client. Nel prossimo paragrafo entreremo più nello specifico degli SharedObject.

3.2.1 Gli SharedObject

Gli SharedObject servono a condividere dati tra i client. Sono di due tipi: quelli locali e quelli remoti. Gli SharedObject locali sono una sorta di cooky che possono essere salvati sul disco locale da un filmato allo scopo di mantenere dell'informazione permanente come ad esempio le preferenze dell'utente nell'uso del filmato. Gli SharedObject locali sono in realtà una funzione supportata anche solo dal FlashPlayer e non richiedono l'uso del Communication Server. Gli SharedObject remoti invece necessitano del Communication Server e servono a memorizzare dati in remoto. Un client flash pubblica o si connette ad uno SharedObject remoto e riceve dei messaggi attraverso i quali viene aggiornato sui dati contenuti nello SharedObject ogni volta che un client li modifica. Ogni client inoltre, può mandare dei messaggi, come l'invocazione di metodi in remoto, a tutti i client che sono connessi ad un particolare SharedObject. Gli SharedObject remoti possono essere temporanei oppure persistenti durante le diverse sessioni di una applicazione. Ogni client che vuole accedere ad uno SharedObject remoto, deve prima di tutto essere connesso ad una applicazione sul Communication Server. Avvenuta la connessione, ogni client può creare nuovi oggetti remoti da condividere con gli altri client oppure può connettersi ad un oggetto già esistente. Attraverso la chiamata al metodo statico SharedObject.GetRemote, il client ottiene un riferimento all'oggetto remoto attraverso il nome passato come stringa a tale metodo. Il nome identifica lo SharedObject. Infine il client invocando il metodo connect, ottiene un messaggio di sincronizzazione. Affinché i dati contenuti nell'oggetto in locale e in quello remoto coincidano, è necessario che il client abbia definito un metodo onSync che verrà invocato dal Server ogni volta che un client aggiorna l'oggetto condiviso. La figura 7 mostra quanto detto finora.

(15)

Figura 7

A connessione avvenuta tra l'oggetto locale e quello remoto, tutte le modifiche da parte di un client all'oggetto locale, verranno trasmesse al server il quale manderà dei messaggi di sincronizzazione a tutti i client. Nella figura si vede come il riferimento all'oggetto condiviso myRemObj viene aggiornato dal client 1 con il valore di 4 per il campo x, tramite la semplice operazione di assegnamento. Questa operazione provoca l'aggiornamento dell'oggetto sul server il quale a sua volta si occupa di sincronizzare gli altri client. Ogni messaggio di sincronizzazione contiene un codice che descrive la natura del cambiamento avvenuta su quell’oggetto remoto. Ad esempio, quando un client si connette per la prima volta ad uno oggetto remoto, il codice del messaggio di sincronizzazione ha il valore di clear. Il valore success indica che il client ha aggiornato con successo il contenuto dello SharedObject. Il valore change significa che un client ha aggiornato lo SharedObject e quindi bisogna aggiornare la copia locale di quello oggetto.

Figura

Figura 2 Con la prima richiesta il browser  ottiene il file Filmato.html,  per il quale scarica successivamente il file Filmato.sw
Figura 4 Il protocollo HTTP viene usato dai browser per scaricare il filmato Flash che implementa  il client

Riferimenti

Documenti correlati

Thunderbolt e il logo Thunderbolt sono marchi registrati di Intel Corporation negli Stati Uniti e/o in altri Paesi.. In attesa di brevetto .© 2021 Kensington Computer Products

• Punteggio associati: il campo non è editabile, sarà valorizzato in automatico dal sistema al termine della presentazione dell’istanza. • Scostamento %: il campo non è

Durata del lampo (T=0,5) 1/800-1/8500S – FREEZE FINO A 1/19000S Ricevitore radio incorporato COMPATIBILE CON TUTTI I RADIOCOMANDI JINBEI. Lampada pilota

Per ogni categoria ali- mentare è stata identificata una precisa porzione di consumo raccomandata in funzione della fascia di età.. In alcuni casi la proposta di una precisa

le misure minime e massime sono indicative e variano in base al vetro ed alla ferramenta

IL MIO SCOPO COME PADRE (RUOLO) È DI ESSERE PRESENTE, AMOREVOLE E AFFIDABILE (VALORI), CAPACE DI SOSTENERE E PROTEGGERE I SOGNI E LE AMBIZIONI DI MIO FIGLIO (FARE COSA), PERCHÉ

o Concorrere, nella misura prevista dagli appositi regolamenti, alla registrazione delle informazioni riguardanti le attività svolte in aula e la valutazione delle stesse

In mancanza di dati tossicologici sperimentali sul prodotto stesso, gli eventuali pericoli del prodotto per la salute sono stati valutati in base alle proprietà delle