| Create your synchronization |
One of the coolest features of this Framework is that it is possible to code and test the synchronization process directly in the web part of the application. The conversion application will then allow it to be used in the offline version. Here is how it can be done.
The user interface part of the synchronization is done directly in the HTML template screens.
The implementation process is in three parts :
Starting : starting the synchronization is done by launching the specialLink method with the zenengo://startSynchro?{synchro launch parameters}. The launch parameters MUST be URL encoded as in an AJAX request.
Following : when the Synchronization .NET class launches a step update the javascript updateStatus method is called with the description, the stepNumber and the maximum step number, in order to create for instance a progess bar.
Error : when then synchronisation .NET class launches an error, the javascript synchroFail method is called with two parameters, the Exception object Type name and the error message.
Success : when then synchronisation .NET class launches an error, the javascript synchroSuccess method is called without any parameter.
The "server side" NET part MUST be contained within a class implementing the AbstractSyncTask library, which has a following methods.
The .NET class and the .NET assemblies will be referenced in the web.config file as explained bellow.
InitFromParameters(Dictionary<String,String>) : Initialization with the parameters given in the javascript specialLink method.
DoSynchro(SyncProcessInit u) : Launches the synchronization process on a separate thread. The SyncProcessInit object contains only the SyncType property.
Error : when then synchronisation .NET class launches an error, the javascript synchroFail method is called with two parameters, the Exception object Type name and the error message.
Success : when then synchronisation .NET class launches an error, the javascript synchroSuccess method is called without any parameter.
The configuration file contains a special handler section under the activsoft.engine section, which will be removed by the conversion application. This handler references the following configuration sections :
beginSynchro : class Activsoft.Engine.Mobile.Web.BeginSynchroAction, with the synchronizationClass attributes containing the full name of the .NET synchronization files.
getSynchro : Activsoft.Engine.Mobile.Web.GetSynchroExtractor, without any attributes.
noXslRenderer : Activsoft.Engine.NoXslXmlRenderer without any attribute
noXslTransform : Activsoft.Engine.NoXslTransformerGenerator without any attribute
Here are some recommendations to keep in mind while coding the sychronization.
This a simple implementation with a progress bar and a label, the synchronisation is calling a web method.
public SyncClass(IGraphicSyncInteraction runner) : base(runner) { } public override void InitFromParameters(Dictionary<string, string> dico) { // MAJ login and password from the interface login = dico["LOGIN"]; password = dico["PASSWORD"]; } protected override SyncProcessResult DoSynchro(SyncProcessInit i) { monConfig = new Config("db"); String syncUrl = ((NameValueCollection)ConfigurationManager.GetSection("syncConfig"))["syncUrl"]; try { // send event to the UI SyncProcessData d = new SyncProcessData(1, "Synchro", 0, 1, "Suppression des anciennes données"); d.StepNumber = 0; d.MaximumStepNumber = 1; this.PublishProgress(d); monConfig.BeginTransaction(); monConfig.ExecuteNonQuery("DELETE FROM ENTITE"); monConfig.ExecuteNonQuery("DELETE FROM CLIENT"); monConfig.Commit(); ... // Success, send message to the UI return new SyncProcessResult(true, null); } catch (Exception e) { monConfig.Rollback(); if (log.IsErrorEnabled) { log.Error("Erreur de synchro", e); } // Error, push the error to the UI SyncProcessResult re = new SyncProcessResult(false, e); return re; } } protected override void RunOnMainThread(System.Threading.ThreadStart th) { this.Runner.RunOnMainThread(th); }
<handler name="synchro" path="synchro.ashx" defaultTemplate="1"> <actions> <action section="beginSynchro" /> </actions> <extractors> <extractor section="getSynchro" /> </extractors> <renderers> <renderer section="noXslRenderer"/> </renderers> <enginemodule> <session section="secureFactory"/> <params cookie="yoocanmovemobile" xslpath="..\xsl" /> <database section="db"/> </enginemodule> <transformgenerator section="noXslTransform"/> </handler>
<div id="login"> <h1>Identification</h1> <fieldset> <acs:TextBox id="loginField" name="login" init="" maxlength="50" label="Identifiant" labelposition="left"/> <acs:TextBox id="password" name="password" init="" maxlength="50" label="Mot de passe" password="true" labelposition="left" /> <div id="actionLogin" style="clear: both"> <acs:Button id="btn-login" text="Connection" action="login()"/> </div> </fieldset> </div> <div id="text_status"> </div> <br /> <div id="progressbar"> </div>
function login() { specialLink('zenengo://startSynchro?configName=sync&login=' + document.getElementById('loginField').value + '&password=' + document.getElementById('password').value); } function updateStatus(txt, step, max) { var valueBar = 0; if (!(step === undefined) || !(step === null)) { document.getElementById("text_status").innerHTML = txt; } if (!(step === undefined) || !(step === null)) { if (!(max === undefined) || !(max === null)) { valueBar = step/max*100 $("#progressbar").progressbar({ "value": valueBar }); } } } function synchroSuccess() { go('1','30','','','',''); } function synchroFail(typeException, message) { alertBox('the synchronization failed, please contact your technical administrator.'); }