Jabber Update – Part 3

Jabber der dritte. Wir haben uns letztes Mal Gedanken darüber gemacht, wie der Client funktioniert, jetzt ist der Service dran. Zunächst wird eine Datenbank gebraucht, in der alle verfügbaren Updates gelistet werden. Dazu kommt eine Anwendung, die der Datenbank mit Schlüssel und dem genauen Verzeichnis auf der lokalen Platte, wo sich die Dateien für die entsprechende Installation befinden einen Eintrag hinzufügt. Die Anwendung wird, wenn sich irgendwas geändert hat einfach nochmal aufgerufen, und dann gibt der Server beim nächsten Update die neuen Infos zurück.

Dann gibt es einfach eine kleine Konsolenanwendung, die den Server startet(mittels AppSpace). Jetzt passiert der erste Schritt vom Update:

  • Step 1 – Benutzer klickt auf Update

Ok, der Benutzer will also seine Anwendung aktualisieren, der UpdateManager geht ins Netz, sucht sich den Service und schickt ein Telegramm mit den Informationen über die Anwendung, die gerade läuft. Der Service sucht nach dem Schlüssel in der Datenbank, und gibt die aktuelle Version der Anwendung an den Client zurück.

  • Step 2 – Updatebeginn

Der Client empfängt die Antwort, wenn die Version vom Service neuer ist als die eigene, wird ein Dialog angezeigt, und der Benutzer kann sich entscheiden, ob er das Update installieren möchte. Wenn das so ist, wird sofort ein weiteres Telegramm an den Service geschickt, mit der Bitte das Update zu starten. Sobald der Service diese Information erhält startet er intern eine Klasse mit einer eindutigen ID, die beginnt die Dateien auszulesen, und zunächst ein Telegramm zum erstellen neuer Dateien an den Client zurücksendet, was die ID enthält.

  • Step 3 – Update

Der Client erstellt die Dateien und schickt die ID wieder zurück. Dann werden auf dem Service nach und nach alle Bytes der Dateien gelesen und verschickt(immer 50kB in einer Nachricht). Zwischen dem Versenden dieser Nutzdatentelegramme wird zwischendurch immer wieder auf die Antwort des Clients gewartet, der die Dateien nach und nach auf die Platte schreibt und immer ein OK mit ID zurückliefert, was verhindert, dass die Nachrichten in der verkehrten Reihenfolge eintreffen, aber vor allem dafür sorgt, dass die Leitung nicht überfüllt wird, und der Client erst gar nichts erhält, und dann alles auf einmal. Denn wenn beispielsweise der Service alle Telegramme sofort mit einer Reihenfolgenummer losschicken würde, müssten alle Bytes gleichzeitig durch die Leitung, was bei größeren Dateien also mehreren Megabyte bis Gigabyte entsprechen würde. Es gäbe dann wahrscheinlich irgendwann ein Timeout, aber auf jeden Fall würde der Client zum Schluss mit einer Flut aus Nachrichten überschwemmt werden, die er gar nicht alle auf einmal bearbeiten kann. Ein Abbruch des Updates seitens des Clients wäre dann auch nicht möglich.

  • Step 4 – Ready

Der Server vermeldet die Fertigstellung des Updates nach dem letzten erfolgreich versandten Bytepacket. Dann startet der Client die Installer-Datei und die Installation kann beginnen!

Hier nochmal die Kommunikation im Detail:

Jabber Update – Part 2

Nochmal zurück zu Jabber und Updates. Wir wollen jetzt einen Schritt weiter gehen, von der grauen Theorie weg jetzt einfach mal eine Bibliothek implementieren, die die Update Funktion kapselt. Dazu brauchen wir zuerst ein API, was die Anwendung intern aufruft, um das Update durchzuführen. Wir beschäftigen uns also erst einmal mit der Client-Seite der ganzen Geschichte, und gehen jetzt mal davon aus, dass die Dateien schon auf dem Server registriert sind, und einfach als Bytes verschickt werden können, wenn der Client sie mit den Informationen zur Anwendung(Anwendungsname), über die diese identifiziert werden anfordert. Wie dann konkret der Service aussieht, darum kümmern wir uns später. Also erstellen wir doch einfach mal eine Klasse AppUpdateManager mit den Methoden BeginUpdate() und EndUpdate(). Wie man sicherlich schnell festellt handelt es sich hier um eine asynchrone Ausführung, logisch, weil ich als Anwender keine Lust hab die ganze Zeit eine blockierende Anwendung anzuschauen, während das Update läuft, und untätig rumzusitzen. So kann die Anwendung weiter verwendet werden, und das Update läuft einfach im Hintergrund ab. Wenn der Benutzer die Anwendung beendet kommt dann eben eine Message-Box, und fragt ihn, ob er das Update, wenn es noch nicht fertig ist, wirklich abbrechen will. Nur Pech, wenn die Anwendung abstürtzt ;-) Der UpdateManager kommuniziert dann über Jabber mit dem Server und lädt sich das Update in das aktuelle Temp Verzeichnis(vom aktuell angemeldeten User) runter. Dann startet er die MSI Datei(wieder asynchron, um dann noch sofort anschließend bevor die Installation überhaupt richtig gestartet ist noch den nächsten Schritt auszuführen), und löst dann ein Ereignis aus, auf was sich die Anwendung vorher registriert, und was diese beendet, da es wenig Spaß macht eine Anwendung frisch zu installieren, die gerade noch läuft. Soweit die Client Seite, es braucht jetzt nur noch der Code:

// Noch die aktuelle Assembly mitgeben, damit der UpdateManager weiß, was genau er aktualisieren soll
AppUpdateManager uManager = new AppUpdateManager(Assembly.GetExecutingAssembly());
uManager.Restart += delegate
{
    // hier irgendwie die Anwendung beenden
};
uManager.BeginUpdate();

eingefügt zu werden, und dann läuft das Update los. Allerdings sollte man peinlichst darauf achten, wenn die Anwendung geschlossen wird uManager.EndUpdate() aufzurufen, da sonst das Update im Hintergrund weiterläuft, was (vor allen Dingen wenn es dann fertig ist, und auf die tote Oberfläche zugreifen will) größere Komplikationen nach sich ziehen kann.
Im nächsten Teil geht es dann um die Serverseite, aber soweit erstmal:

Happy Jabber

Jabber my Updates

Mit dem Neuron Net Builder kommt auch die Update – Funktion über  das Internet.  Man könnte jetzt denken die laufen über den FTP Server, gänge wahrscheinlich auch schneller, aber es soll mal eine Lösung gefunden werden, bei der kein FTP, oder sonst ein Server aufgesetzt werden muss. Das heißt das Update basiert rein auf der Kommunikation von zwei Rechnern, nämlich  meinem Laptop, und dem Computer, von dem aus das Update durchgeführt wird.  Daraus ergibt sich allerdings das Problem, dass ich mit herkömmlichen Methoden(das heißt zum Beispiel  normales  http, oder tcp, oder  sonstwas) nur im lokalen Intranet kommunizieren kann, es sei denn ich registriere das Zeug im IIS, bezahl eine teure Domain, und so weiter. FTP Server aufsetzen ist also wesentlich billiger und  weniger aufwendig(falls man sich  mit einem freien zufrieden geben kann). Wir können unser Problem auf diese Art und Weise also nicht lösen. Wir brauchen also eine Kommunikation über das Internet, wobei sich der Computer, der das Update zieht mit irgend einem Server im Internet verbindet, den ein Williger ins Netz stellt. Dann muss ich  dort eine Session aufmachen, und alle Anfragen, die der Server vom Computer, der das Update zieht an meine Machine weiterleiten, und dann auf dem gleichen Umweg wieder zurückschicken. So brauch ich keinen Server aufzusetzen, sondern alles läuft über diese Zwischenstelle. OK, so was denk ich mir natürlich nicht aus, diese Lösung hat den Namen Jabber(oder XMPP = Extensible Messaging and Presence Protocol).

Das funktioniert also, bliebe noch zu klären, wie ich genau meine Anwendung jetzt verteile.

  1. Was wird verteilt
    Die  Installationsdateienen liegen als msi vor, die  noch  mit zusätzlichen Dateien übertragen werden müssen(normalerweise setup.exe)
  2. Wie wird das über die Leitung geschickt?
    Hier kommt die Open Source Bibliothek namens AppSpace von Xcoordination zum Einsatz, welche  das Versenden und Empfangen von Nachrichten via Jabber ermöglicht(sie selbst setzt auf der AgsXMPP  Bibliothek auf,  die die Jabber – Kommunikation allgemein kapselt). Die Frage ist nun, wie viele Bytes meiner Installationsdateien in solch einer Nachricht enthalten sein sollten. Es macht zum Beispiel keinen Sinn immer nur einige wenige Bytes zu versenden, da ja auch der Header der Nachricht, und alles zugehörige noch mitgeschickt werden muss. Ich habe einfach mal immer 50  kByte Nutzdaten  geschickt, der  Wert kann einfach als  Konstante im Programm geändert werden.
  3. Empfangen
    Dann werden die Bytes vom Empfänger empfangen, in irgend  ein temporäres Verzeichnis kopiert, und dann wird die  msi Datei ausgeführt.
  4. Fertige Updatefunktion ohne  FTP Server, eigene Website oder ähnliches