I sistemi di trasformazione digitale presentano frequentemente architetture complesse in cui i vari componenti devono comunicare fra di loro, spesso in tempo reale.
Alcuni esempi di questo tipo di comunicazioni sono:
- Messaggistica integrata con lâapplicazione, stile WhatsApp.
- Notifica di eventi rilevati da sistemi IoT come allarmi, stato degli impianti, eccetera.
- Comunicazione del cambio di stato di un documento da una sessione alle altre.
- Acquisizione di informazioni dal backend da parte di un device.
- Allineamento di un database offline con la controparte cloud.
Instant Developer Cloud include un sistema di sincronizzazione e di scambio di messaggi fra sessioni applicative e device in grado di risolvere i casi sopra indicati. Le caratteristiche principali sono le seguenti:
- Gestione automatica della connessione con la controparte nel cloud.
- Scambio di messaggi in tempo reale fra sessioni e applicazioni.
- Gestione di messaggi in modalitĂ offline.
- Gestione di operazioni remote sui documenti.
- Sincronizzazione dello stato dei documenti fra database offline e backend cloud.
Architettura delle sessioni #
La sincronizzazione mette in comunicazione le varie sessioni applicative, sia quelle in esecuzione nel server nel cloud, che quelle in esecuzione nei device degli utenti. Le prime vengono chiamate sessioni online, le seconde sessioni offline o sessioni locali.
Ă importante notare che dal termine sessione offline deriva il concetto di applicazione offline utilizzato in questa documentazione. Si definisce infatti applicazione offline unâapplicazione in grado di funzionare anche in assenza di connessione internet e che può essere sincronizzata con il server ogni volta che il device in cui è installata si riconnette a internet.
Per far sĂŹ che una sessione locale possa comunicare con le altre sessioni, sia quelle online che quelle locali nei dispositivi, la sincronizzazione crea per ogni dispositivo connesso una sessione proxy nel cloud. Si chiama proxy perchĂŠ essa rappresenta il device allâinterno del server per quanto riguarda le operazioni di sincronizzazione.
Lo schema alla pagina seguente illustra la connessione tra le sessioni di vario tipo: se, ad esempio, la sessione server riceve un evento IoT come lâattivazione di un allarme, essa può comunicarlo a tutte le sessioni interessate, sia quelle online che quelle locali, in esecuzione nei device.
Lâinvio dei messaggi ai device potrĂ avvenire anche se sono momentaneamente offline, in quanto sia il server nel cloud che i device possiedono un data store della sincronizzazione che memorizza i messaggi non volatili in modo che possano essere consegnati anche se la connessione non era attiva al momento dellâinvio.
Le sessioni locali e online possono appartenere anche ad applicazioni diverse. Ad esempio lâapplicazione nel server può essere quella di back office, mentre quella sui device viene usata dagli utenti finali. Nel server, inoltre, possono essere presenti piĂš applicazioni diverse e la sincronizzazione può essere configurata per inviare messaggi anche tra sessioni che non appartengono alla stessa applicazione. Questo può essere utile se le varie applicazioni modificano gli stessi dati o appartengono allo stesso sistema informativo.
Configurazione della sincronizzazione #
Il sistema di sincronizzazione deve essere configurato per ogni tipo di sessione, sia nel server che per quelle locali ai device. In questo paragrafo viene analizzata la configurazione base per attivare la sincronizzazione; nei paragrafi successivi verranno aggiunti ulteriori parametri in funzione dei servizi che si desidera utilizzare.
Sessioni online #
Per le sessioni online, la configurazione della sincronizzazione deve avvenire allâinizio della sessione, quindi:
- Nellâevento app.onStart per le sessioni di tipo browser o di tipo server.
- Nellâevento app.onCommand per le sessione di tipo REST.
- Nellâevento app.sync.onConnect per le sessioni di tipo proxy.
La prima proprietà da configurare negli eventi di inizio sessione è app.sync.dataStore, che serve per comunicare alla sincronizzazione il database da utilizzare per memorizzare i messaggi permanenti, cioè quelli che devono essere inviati ai device anche se sono momentaneamente disconnessi. Ad esempio:
app.sync.dataStore = App.NwindDB;
La seconda proprietà è relatedApps, che rappresenta il nome dellâinstallazione delle altre applicazioni che devono ricevere i messaggi di sincronizzazione, impostate come stringa o array di stringhe. Questa proprietĂ deve essere impostata solo se nel server sono installate due o piĂš applicazioni che trattano gli stessi dati da sincronizzare. Ad esempio:
app.sync.relatedApps = âbackofficeâ;
La terza proprietà è topics, un oggetto JavaScript che rappresenta i messaggi ai quali è interessata la sessione. Ogni sessione, infatti, non deve ricevere tutti i messaggi delle altre sessioni, ma solo quelli che la riguardano direttamente. I topics verranno spiegati nei paragrafi successivi. Ecco un esempio:
app.sync.topics = [âutente0â, âutente10â, âutente2â];
Sessioni locali (offline) #
In aggiunta alle proprietĂ delle sessioni online, quelle locali devono specificare serverUrl e appName, di solito nellâevento onStart. La prima rappresenta il server nel cloud a cui ci si deve collegare, la seconda il nome dell’installazione dellâapplicazione che gestisce la sincronizzazione. Ad esempio:
if (app.runsLocally()) {
app.sync.serverUrl = app.sync.serverUrl ||
"https://myserver.instantdevelopercloud.com";
app.sync.appName = "backoffice";
}
Il metodo app.runsLocally restituisce true se la sessione è locale, cosÏ da poter inserire il codice aggiuntivo solo in questo caso.
Si noti che serverUrl viene impostata solo se è vuota, perchĂŠ il framework di Instant Developer Cloud può preimpostare questa proprietĂ quando lâapplicazione viene lanciata dallâIDE in anteprima FEBE (Front End – Back End).
Infine è possibile impostare la proprietà autoConnect, che rappresenta la modalità di gestione della connessione. Il valore di default è App.Sync.autoConnectTypes.automatic, che crea una connessione solo al bisogno e poi la disattiva dopo un tempo prestabilito di inattività .
Nella pratica comune, però, è preferibile lasciare la sessione sempre connessa al server di sincronizzazione in modo che possa rimanere aggiornata in tempo reale. Per ottenere questo risultato, inserire il seguente codice:
app.sync.autoConnect = App.Sync.autoConnectTypes.alwaysConnected;
Attivazione della sincronizzazione #
Mentre le sessioni online sono sempre connesse al proprio sistema di sincronizzazione, per quelle locali la sincronizzazione deve essere esplicitamente attivata tramite la proprietĂ enabled. Quindi, dopo aver impostato le proprietĂ di configurazione, quando si deve attivare la sincronizzazione occorre scrivere il seguente codice:
app.sync.enabled = true;
Fintanto che questa proprietà rimane attiva, la sessione locale gestirà la sincronizzazione. Questo non significa che il device rimarrà sempre connesso al server. Esso si può disconnettere e poi riconnettere in automatico, a seconda del valore della proprietà autoConnect, dello stato della connessione e dello stato del device.
Si segnala che se la proprietĂ autoConnect è impostata a App.Sync.autoConnectTypes. manual lâattivazione della proprietĂ enabled non apre mai la connessione; sarĂ necessario usare i metodi connect e disconnect dellâoggetto sync per gestirla.
Nellâimmagine seguente viene riportato il ciclo di vita della connessione allâinterno di una sessione locale.
Attivazione della connessione #
Quando il framework tenta di aprire la connessione, viene contattata lâapplicazione specificata del server di sincronizzazione e, lato server, viene creata una sessione proxy relativa al device che sta tentando di aprire la connessione.
Nella sessione proxy, cioè lato server, viene notificato lâevento app.sync.onConnect che permette alla sessione di determinare se il device ha il diritto di connettersi o meno. Se nel codice dellâevento viene attivata la proprietĂ cancel del parametro options, la connessione lato device viene chiusa e la proprietĂ app.sync.enabled della sessione locale viene disattivata per evitare inutili tentativi di riconnessione. In questo caso anche la sessione proxy viene terminata immediatamente.
Si noti che viene aspettato il completamento dellâevento onConnect prima di dare il consenso al device, quindi è necessario che il codice interno allâevento non richieda troppo tempo per essere eseguito. In caso contrario, può scattare il timeout di connessione della sessione locale che per default è 5000 ms, valore modificabile tramite la proprietĂ app.sync.connectionTimeout.
Se si verifica un timeout di connessione mentre la connessione al server è giĂ attiva, nella sessione locale viene resettata la proprietĂ app.sync.enabled. Infatti, il verificarsi del timeout è determinato dal fatto che lâevento onConnect lato server è stato troppo lento e questo può essere segno di un sovraccarico. Tentando di nuovo la connessione, il sovraccarico potrebbe aumentare.
La stessa cosa avviene se lâevento onConnect lato server genera unâeccezione. Anche in questo caso è bene che la sessione locale non tenti di nuovo la connessione in maniera automatica.
In ogni caso, al termine del tentativo di connessione, la sincronizzazione notifica lâevento app.sync.onConnect anche alla sessione locale passando come parametri lo stato della connessione e lâeventuale motivo della mancata connessione da parte del server.
Vediamo un esempio di codice di onConnect nelle sessioni online.
app.sync.onConnect = function (options)
{
// Solo online!
if (!app.runsLocally()) {
app.sync.dataStore = "ToBuyDB";
// Carico lâutente in base ai dati passati come topics
if (app.sync.topics)
app.account = yield App.TBBE.Account.loadByKey(app, app.sync.topics);
//
if (!app.account) {
options.cancel = true;
options.cancelReason = âUser not foundâ;
}
}
};
Chiusura della connessione #
Dopo che la connessione è stata instaurata, essa viene gestita in automatico dal sistema di sincronizzazione. Ci sono alcune situazioni in cui la connessione viene chiusa:
- Mancanza di segnale di rete del device.
- Applicazione in background.
- Device bloccato.
- app.sync.enabled impostata a false.
- se autoConnect non è âautomaticâ, dopo il timeout di inutilizzo della sincronizzazione, che per default è 30 secondi.
In tutti questi casi, viene lanciato lâevento onDisconnect sia nella sessione locale che in quella online e poi questâultima viene terminata. Se il device effettua un altro tentativo di connessione, esso avverrĂ su una sessione proxy diversa dalla precedente.
Lâevento onDisconnect della sessione locale può essere utilizzato per avvertire lâutente che la sincronizzazione non è disponibile. Questo può essere utile soprattutto se lâapplicazione non ha dati locali ma si basa su chiamate remote al server.