Donnerstag, 28. April 2011

Webmail client. Outsorcing der Mails

Emails unkompliziert von überall bearbeiten
Das mobile Office ist ja schon lange Realität. Die meiste Arbeit ist Emails, Dateien bearbeiten und Dateien versenden. Nun habe ich lange nach einer Möglichkeit gesucht, den eigenen Mailserver zu ersetzen und doch so optimal wie möglich zu arbeiten. Klar die Grossen wie Gmail und Hotmail sind da auf jeden Fall zu berücksichtigen. Also habe ich nun mal alle getestet und meine Erfahrung hier aufgeschrieben. Als Alternative habe ich Zimbra genommen. Ziel war es nicht nur einen guten Mailclient mit Kalender und dergleichen zu haben, sondern auch eine eingebaute Dateiverwaltung. Denn nur so kann man am Strand beim Cocktail alle Arbeiten verrichten. Mein grosses Ziel ist es ein wartungsfreies online Office zu haben. Der Email-Baustein ist das wichtigste, da ja der tägliche Helfer.

Was wurde bewertet?
Klar das Emailhandling (versenden, bearbeiten), verschiedene Accounts einbinden auch von anderen Domains, die einem gehören. Also Einbindung von anderen POP und IMAP Konten. Kalenderfunktion, hier auch die Möglichkeit unkompliziert die Emails mit dem Terminen zu verbinden. Dateiverwaltung (anlegen, editieren) und die Möglichkeit diese mit Emails zu verbinden. Also wie die gängigen Bereiche mit einander arbeiten. Auch die Erweiterung ist wichtig, so dass man evtl eigene benötigte Operationen machen kann. Natürlich sollte alles super einfach auf bestehende mobile Telefone passen.

Hotmail
Ganz klar der Profi unter den Weboffice angeboten. Echt gut. Dazu offeriert MS auch gleich noch ein üppigen Speicherplatz und die Möglichkeit unter Windows das Laufwerk zu mounten. Geradezu genial ist die Möglichkeit Hotmail via Exchange Zugang einzurichten. Daneben bietet MS nun auch mit Office365 eine super Lösung, zumindest auf Papier. Hier deckt sich das Mailangebot in der Funktionalität mit der von Hotmail. Konnte es noch nicht ausgiebig testen, da schon gleich zu beginn das gleiche Problem mit den Attachments wie bei Hotmail aufkam. Als erstes fällt auf, dass der Dienst etwas langsam ist. Bietet aber vieles. Vorallem ist es auch möglich verschiedene Soziale Dienste zu integrieren, diese werden auch auf den Chatbereich ausgedehnt. So kann man mit allen Kontakten auf jeder Applikation chatte, egal in welchem sozialen Netzwerk der Konversationspartner gerade ist. Es wirkt aber etwas unordentlich. Der Email Bereich ist in gewohnter Form und man findet sich schnell zurecht. Gut ist das die Liste mit den Emails offen bleibt, während man den Inhalt lesen kann. Wie im Outlook. Es fehlt die Möglichkeit eine Email mit einem Todo oder Kalendereintrag zu verbinden. Gerade dies ist oft für den BusinessAlltag nötig. So kann man wunderbar vom Termin auch gleich an die zugehörigen Emails gelangen. Leider haben dies die Leute von Microsoft nicht realisiert. Die Online-Kontakte werden angezeigt und das auch Dienste übergreifend. Es gibt einfach zu bedienende Aufräumaktionen direkt aus der Emailansicht heraus. Man kann die Emails mit nur Flaggen und nicht mit verschiedenen Tags versehen. Cool ist der Standard Filter, so dass man alle Emails mit Bilder oder Office Dokumente listen kann. Es gibt eine Suche, welche auch verfeinert werden kann. Beim Email verfassen, kann man auch Texte formatieren und einen Spellcheck gibts auch. Sehr gut ist die Möglichkeit direkt beim Verfassen eines Textes Suchanfragen zu starten und die Inhalte aus dem Internet direkt zu einbinden. Die Suche kann auch nach den verschiedenen Medien gefiltert werden. Mit einem Klick auf den Suchtreffer, landet die URL samt Beschreibung in der Email. Genauso auch Bilder. Diese kann man dann auch editieren. Man kann Dateien per Upload hinzufügen, jedoch nicht auch die hinterlegten Dateien zugreifen. Damit hat man das Problem, dass man erst die online Dokumente herunterladen muss, um diese wieder aufzuspielen. Das ist sehr schlecht gelöst. Da merkt man deutlich, dass die Produkte unabhängig voneinander sind. Google hat das Gleiche Problem. Man kann externe Accounts einbinden, sogar ganze Domains umstellen. So kann man hotmail als seinen Mailserver nutzen. Dazu muss man Zugriff auf den DNS Eintrag seiner Domain haben. Das Abholen von exterenen Accounts gehört bei allen zum Standard. Der Eingebaute Messenger spricht mit allen Kontakten, egal auf welcher Plattform der Kontakt sich befindet.

Der Kalender verfügt über verschiedene Ansichten und man kann auch weitere Kalender erstellen. Ebenso ist das Einbinden von externen Kalender kein Problem. Hier ist auch die Todo-Liste. Das Anlegen eines Eintrags geht im Schnellmodus und im erweiterten Zustand, so dass man gleich mehr Optionen einstellen kann. Der Kalender kann auch für andere frei gegeben werden, für sowohl andere Hotmail Nutzer als auch komplett öffentlich. Da kann man sehr genau die Freigaben einstellen. Natürlich kann man andere Teilnehmer wie gewohnt zu einen Termin einladen.

Die Weboffice Applikation ist echt gut. Allerdings ist die Integration nicht optimal gelungen. Man klickt auf den Office Bereich und erhält dort wiederum eine Startseite. Das ist erstmal nicht so weit störend, doch wenn man öfter mit den Dokumenten arbeitet und zwischen den Email hin und her klicken muss, ist das echt nerven aufreibend, zumal die Geschwindigkeit sehr zu wünschen übrig lässt. Hier hat man auch zugriff auf SkyDrive, den online Speicherplatz, der auch 25GB kostenfreien Platz beinhaltet. Das ist echt enorm. Leider auch hier wieder erst sichtbar über eine Startseite. Für das tägliche Arbeiten wird das einfach zu viel. Man kann Dateien mit anderen teilen und freigeben. Genauso kann man mittels Email, direkt Dateien auf den Skydrive einspielen. Diese Option ist sehr geschätzt und meine Hauptfunktion bei Alfresco. Eben mal schnell die Email mit der Rechnung auch gleich in den Rechnungsordner und zur Buchhaltung senden. Und das nur mittels einem Klick. Die Verknüpfung mit den verschiedenen Tools ist leider noch nicht abgeschlossen und bringt auch schon wegen der Wartezeit Frust. Natürlich ist hier auch das Problem für den einen oder anderen, dass die Daten bei jemanden anderes liegen der auch schon aufgrund der AGB mitlesen darf. Eine konkrete Anfrage, ob denn nun MS auch die Texte und Daten liest, wird immer nur lapidar beantwortet. Man windet sich und auch nach mehrmaligen, direkten Fragen, ob ein Weboffice Dokument nun gelesen wird oder nicht, wir man nur hin und her gesendet. Also denke ich ganz klar, dass die Daten nicht geheim bleiben, wenn es MS nicht will. Wenn man keine grosse Nummer denke ich, ist das Risiko gering.

Gmail
Der ganz grosse unter den Webmailer. Die ersten die einen richtig guten Webmailer kostenlos für alle angeboten haben, der auch noch richtig schnell ist. Die Emails kann man mit verschiedenen Tags belegen und verwaltet so statt in Ordner die Mails in logischen Markierungen. Das Design gewohnt schlicht und vermutlich auch deswegen gut. Man kann sich die verschiedensten Minielemente von den einzelnen Tools wie Kalender und Dokumente im Webmail Bereich einblenden lassen. Direkt eingebunden ist die Todoliste und das Chatfenster. Anders als bei hotmail scheint der Chat aber auf Google beschränkt zu sein. Dazu gibt es die Möglichkeit kleine Tools aus dem Google Labs einzubinden. Die Emails werden in Konversationen zusammen gestellt. So hat man einen sehr guten Überblick über die Email Konversation. Dazu blendet Gmail geschickt unnötige Wiederholungen bei Antworten aus. Vieles geht intuitiv und wirkt durchdacht. Man kann sehr leicht auch von verschiedene Absender aus versenden, was sehr praktisch sein kann, wenn man unterwegs ist und eine Mail mit einem bestimmten Absender versenden will. Dazu muss man nur einmal die besagte Emailadresse bestätigen.

Der Kalender ist super. Man kann Termine mit einem Klick anlegen und Google parst den Text und legt entsprechend den Eintrag an. So kann man auch "20:00 zahnarzt" schreiben und der Termin wird auf 20:00 gelegt. Hier kann man auch kleine Helfer aktivieren und mehrere Kalender anlegen und auch diese entsprechend freigeben oder öffentliche und freigegeben Kalender einbinden. Das Einladen von Teilnehmer an Termine ist ebenso enthalten, wie die Erinnerungsfunktion. Was gut ist, ist die Möglichkeit auch Anhänge zu einem Termin zu hinterlegen. Hier kann man sehen, wie es auch für das Mail gehen sollte. Man kann Dateien hochladen oder direkt aus der Google Text & Tabellen App auswählen. Auch die Erinnerung kann beliebig geschachtelt werden. So kann man mehrmals daran erinnert werden und das auf verschiedene Weisen (Email, Popup im Browser). Zwar ist das die Parade Diszilin von MS Exchange doch in hotmail vermisst, bietet Google die Möglichkeint einen geeigneten Zeitpunkt zu finden, um das Termin planen zu vereinfachen. Leider fehlt die Verbindung zu den Emails. Man kann aber Emails auf die Todoliste setzen und diese kann auch mit Datum ausgestattet werden. Auch bei Google kann man weitere externe Accounts einbinden, allerdings kann man nicht weitere Gmail accounts verbinden. Das ist ärgerlich wenn man zum Beispiel neben dem normalen Gmailaccount auch noch einen Corporate Account hat. So kann man auch hier den kompletten Mailverkehr für seine Domain über Google laufen lassen.

Google bietet mit Text & Tabellen ein sehr interessantes Werkzeug, um Dokumente zu verwalten und zu erstellen. Diese Tools sind durchaus brauchbar und nicht zu unterschätzen. Allerdings sind es natürlich keine vollwertigen Desktop-Word Ersatz und Excel Programme, aber für Briefe, auch geschäftsbezogene eignen sich diese Dienste hervorragend. Die Übersicht der Dateien ist etwas gewöhnungsbedürftig. Aber es gibt eine Vorschau. Man kann Dokumente freigeben und mit anderen gemeinsam zur gleichen Zeit bearbeiten. Super bei Kalkulationen die über Skype besprochen werden. Dabei kann man auch live Diskussionen über ein Dokument erstellen und diese werden auch zum Dokument gespeichert. Das Dokument kann in verschiedenen Versionen gespeichert werden. Auch der Export bietet alles was man braucht. Gerade das Versenden des Dokuments ist hier viel besser als bei hotmail gelöst. So kann man das Dokument auch direkt als PDF Attachment anhängen. Wie bei hotmail kann man auch hier das Dokument online erreichbar machen und die URL an Dritte weiter geben. Leider fehlt auch hier die direkte Verbindung zu Gmail. Man kann jeweils nur ein Dokument per Email versenden. Man kann nicht erkennen wieviel Speicherplatz man hat, jedoch kann man auch wie bei hotmail Dateien hinterlegen. Allerdings ist ein direkte Einbindung als Laufwerk in Windows nicht möglich. Sehr bedauerlich ist es, dass man nicht direkt aus dem Gmail heraus auf die Dateien zugreifen kann. Man muss alle herunter laden und dann wieder aufspielen. Das ist wirklich ein Armutszeugnis, da google sonst so innovativ ist.

Eines muss man aber sagen, die Geschwindigkeit ist sehr gut. So kann man auch in hektischen Situationen die Apps nutzen, ohne gleich nervös auf die Maus zu hämmern. Über das Mitlesen von den Daten muss man bei Google wohl nix schreiben.

Zimbra
Der letzte im Bunde ist Zimbra. Zimbra ist eine komplette Email/Groupware Suite. Ist nicht direkt kostenlos, aber dafür gibt es eine kostenfreie Community Version, die man auf einen Server installieren kann. Das ist auch der grosse Vorteil. Die Daten bleiben auf den eigenen Servern. Server kann man mittlerweile sehr günstig erhalten. Natürlich gibt es auch Anbieter, welche nur einen Emailaccount anbieten.  Die Webmail Oberfläche kann man in verschiedene Designs haben. Man kann eigene Tags anlegen und die Dateien wie gewohnt in Ordner verwalten. Externe Accounts und Domains einbinden und von aussen per Imap oder POP3 Emails abrufen. Auch hier kann ein Minikalender in der Mailansicht einblenden lassen. Zimbra lässt sich leicht mit Addons, sogenannte Zimlets erweitern. Diese kann man aus dem freien Entwickler Portal einbinden oder selbst schreiben. Damit kann man Zimbra wirklich extrem erweitern, da oft sehr nützliche für den Business-Alltag benötigte Elemente bereitgestellt werden. So kann man die Social Welt einbinden und neben Facebook auch seine Twitter-Accounts komfortable verwalten und nutzen. Die Mails können auch im Koversationsmodus wie bei Gmail angezeigt werden. Dabei ist hier eine gelungen Mischung zwischen Gmail und hotmail entstanden. Beim Erstellen von Emails hat man dann endlich eine gelungen Kombination von Dateiverwaltung und Email. Attachment in Form von Uploads oder direkt aus dem Online-Storage von Zimbra sind ganz einfach einzubinden. Hat man auch das Alfresco Zimlet installiert, geht dies sogar vom entfernten Alfresco Server. Man kann ganz einfach auch Emails als Anhang einbinden, oder Kontakte. Ideal auch für Firmen ist der eingebaut Messenger, der allerdings nur die vom Server verwalteten User unterstützt. Nice ist hier, dass die Chats wie Emails auch gespeichert und durchsucht werden können. Mails können als Aufgabe oder Termin erfasst werden. Leider ist es sehr umständlich von verschiedenen Absender aus zu versenden. Das ist ähnlich wie bei Exchange sehr umständlich gelöst. Gerade für Leute die auf Verteilerlisten stehen, mühselig, da diese nicht mit der Verteileremailadresse antworten können.

Der Kalender ist ebenso komfortabel wie der von hotmail oder google. Auch hier kann man Kalender freigeben oder externe einbinden. Man kann Termine mit Anhängen belegen und Teilnehmer hinzufügen. Top ist auch die Planer Funktion, wie bei Gmail, ist hier das finden eines gemeinsamen Termins schnell gemacht, sofern die Teilnehmer ebenfalls auf dem Zimbra-Server ihren Account haben.

Frühere Versionen hatten ebenfalls eine WebOffice Paket, das ist nun nur noch für Text vorhanden. Tabellenkalkulation ist verschwunden. Man kann eigene Dateien hinterlegen und diese beliebig freigeben und somit auch einen Fileserver betreiben. Speicherplatzbegrenzung hängt vom eigenen Server ab. Die Ansicht wird wie bei Email gehalten und man findet sich schnell zurecht. Schön ist auch die Vorschau. Wirklich top ist die Möglichkeit die Dateien in Emails als Anhang zu versenden. So lässt es sich arbeiten. Leider kann man nicht wirklich Dokumente bearbeiten. Dennoch ist der Texteditor gut und für viele Arbeiten ausreichend. Die Dateien können mit den Tags belegt werden, so auch die Termine, Kontakte und Todo-Einträge. Das ermöglicht ein Zusammenfassen der verschiedensten Elemente zu einem gesamtheitlichen Kontext. Wunderbar um schnell Daten zufinden. Einige Zimlets erlauben sogar SMS Versand, Einbindung von VOIP und andere oft genutzte Dienste. Allerdings sind einige nur für bestimmte Länder sinnvoll. Aber es ist ja eine offene Schnittstelle und man kann mit steigender Verbreitung von Zimbra auch auf weitere Zimlets hoffen.
VMware hat Zimbra erworben und bietet passende Versionen an. Es bietet sich auch wirklich ideal dafür an, da ein Zimbra Server, viele Dienste einsetzt. Wenn man die Möglichkeit hat, eine virtuelle Maschine einzusetzen, dann hat man es super leicht zu starten. Aber auch ein frisch aufgesetzter Server kann sehr leicht zum Zimbra Server gemacht werden.

Fazit
Wenn man sich ein Wunschprogramm aus den 3 bauen könnte,
würde ich die WebOffice App von hotmail mit den Google Umwandlungskünsten verbinden und die Verwaltung durch Zimbra machen lassen. Die Social Leistung von hotmail und die Einfachheit von Gmail im Einbinden von weiteren Accounts und Emailversender zusammen fehlen dem Zimbra. Neben dem Vorteil der Datensicherheit spricht vieles für Zimbra. Der Nachteil ist, dass man sich um den Mailserver kümmern muss. Auch wenn man das alles automatisiert, bleibt immer mal was an Arbeit hängen. Dennoch ist die Verknüpfung der Bereich in Zimbra vorbildlich gelöst und es macht richtig Spass mit dem Programm zu arbeiten. Die Erweiterbarkeit spricht für Zimbra, wenn man eine grössere Firma mit spezial Wünschen ist.

Freitag, 22. April 2011

Cookies mittels JavaScript bearbeiten

Cookies
Cookies nennt man die kleinen textuellen Informationen, welche vom Browser auf dem Client gespeichert werden. Der Browser stellt in der Regel sicher, dass diese Cookies pro Domain verwaltet werden und beim Aufruf der Domain immer mitgesendet werden. So kann man komfortable kleine Informationen ablegen und den Client wieder erkennen. Sehr sinnvoll, um zum Beispiel die eingestellte Wunschanzeigesprache der Webseite wieder herzustellen. Im Cookie sind in der Regel Key-Value-Pairs gespeichert und diese können auch mit einem Verfallsdatum versehen werden. Da Cookies in der Regel URL-Pfad abhängig gespeichert werden, kann man auch hier einen Pfad angeben, um die Information auch von Unterseiten auf der Startseite zu erhalten.
Cookies auf SelfHTML

Einfache Cookie Behandlung mittels JavaScript
Mit JavaScript kann man diese Cookies auch setzen und auslesen. Leider ist die Funktionalität nicht so gut, also helfen wir uns mit eigenen Funktionen. Das geht zum Glück sehr leicht. Natürlich kann man alles in eine Klasse packen, doch hier soll die Funktion reichen. Es sind auch nur 2. Die Set-Funktion bekommt
den Keynamen vom Key-Value-Pair, den Wert (also Value), evtl ein Gültigkeitsdatum in Millisekunden und einen optional einen Pfad. Das Lesen ist noch einfacher. Wir geben nur den gewünschten Key an und erhalten einen Value. Wenn Key nicht vorhanden ist, erhalten wir eine leere Zeichenkette.

Cookie Funktionen
function cookie_set(name, wert, miltime, pfad) {
  if (navigator.cookieEnabled == false)
    return false;
  var str = name+"="+wert.replace(/;/g,"")+";";
  if (miltime) {
    var ablauf = new Date();
    ablauf.setTime(miltime);
    str += " expires="+ablauf.toGMTString();
 }
 if (pfad)
   str += ' path='+pfad;
   document.cookie = str;
   return true;
}

function cookie_get(name) {
  if (!document.cookie)
    return "";
  var str = document.cookie;
  if (str == "")
    return "";
  var teile = str.split(";");
  for (var a=0;a<teile.length;a++) {
    var pos = teile[a].indexOf("=");
    if (name == teile[a].substr(0,pos))
      return teile[a].substr(pos+1);
  }
  return "";
}

Beispiel Einsatz
Wir möchten je nachdem wie der User auf unsere Seiten gelangt ist, ihm immer wieder die gleiche Startseite zeigen. Ideal um verschiedene Startseiten zu testen. Die Landingpage im Pfad landingpages/ setzt ein Cookie.
Das Cookie wird dann in der eigentlichen Startdatei im Pfad / ausgelesen.

Landingpage:
var filename = "ostern.html";
cookie_set("landingpage", filename, verfallsdatum.getTime(), teile.join("/")+"/");

Eigentliche Startseite:
if (cookie_get("landingpage")) {
  var bereich = cookie_get("landingpage");
  return document.location.href = "landingpages/"+encodeURIComponent(bereich);  
}

Fazit
Mit diesen Funktionen kann man sehr leicht sein Framework ausbauen und eine simple einfache Cookie-Behandlung nutzen. Ausbaufähig ist eine Cookie-Speicherung von komplexeren Werten. Jedoch sollte man nicht vergessen, dass Cookies nicht unbedingt sehr sicher sind, immer an die Domain mitgesendet werden und eigentlich nur für nicht wichtige Bestandteilen gedacht ist. Ich würde keine komplexen Daten dort sichern, da einige Clients die Cookie Unterstützung deaktivieren.

Saso Nikolov

Mittwoch, 20. April 2011

Ajax oder doch lieber Api-Call

Dank JavaScript ist es möglich selbst auch statische Seiten dynamisch zu gestalten. Dabei bietet Ajax die einfache Möglichkeit Elemente nach zu laden. So kann man die Angangsseiten schlank halten und die benötigten Elemente bei Bedarf nach laden. Ajax hat allerdings ein Sicherheitsschutz, der es schwer macht Cluster oder gar verteilte Seiten zu verbinden. Hier ist das Thema Crosssdomain von Bedeutung.

Crossdomain Problem
Aus Sicherheitsgründen ist es einer Webseite nicht erlaubt per Ajax auf andere Subdomains zugreifen zu können. Wenn jemand eine komplette Domain für sich selbst nutzt scheint es erstmals unnötig, doch wenn man Subdomains nutzt und andere ebenso Subdomains mit der gleichen Domain nutzen, wird diese Sicherheitshürde verständlicher. Eigentlich ist das kein grosses Problem, wenn man nur eigene Inhalte vom eigenen Server herunterladen möchte. Doch was ist, wenn man verschiedene Subdomains einsetzen möchte, um zum Beispiele verschiedene Kunden zu unterscheiden und dennoch allen eine gemeinsame Komponente anbieten möchte? Oder man hat soviel Traffic, dass man verschiedene Server nutzt und diese eventuell für Zugriffe aus verschiedenen Kontinenten verteilt hat. Klar man kann nun wieder ein komplexes System mit Loadbalancer und dergleichen aufbauen, doch unser Ziel ist es ja effizient und einfach zum Ziel zu kommen. Vorallem sollten so wenig externe Komponenten wie möglich zum Einsatz kommen. Interessant ist auch die Möglichkeit SSL für das nachträgliche Nachladen zu nutzen, und so die Zugriffspfade für versteckte Dateien zu verstecken. Ein wildcard-SSL-Zertifikat ist schnell erstellt, doch wenige besitzen einen CA, der in allen Browser implementiert ist. Der lästige Browserhinweis ist kaum einem Kunden zu zumuten. Mehrere Zertifikate zu kaufen, ist auch nicht billig. Also könnte man ein Zertifikat erwerben und darüber die SSL Kommunikation machen. Sagen wir mal für die subdomain www. Nun ist es ärgerlich wenn einer eine andere subdomain eingibt, oder eventuell überhaupt keine Subdomain in die Adressleiste des Browser eintippt. Sollten wir diesen Kunden ignorieren? Nein, klar nicht. Ein Umleitung auf die richtige Subdomain ist möglich, doch was ist, wenn Parameter übergeben werden. Diese müsste man auch immer mit umbiegen. Nicht sehr effizient, aber machbar. Wir könnten aber auch als das so sein lassen, wie es ist und statt einer Ajax-Lösung eine andere Methode nutzen, um dynamisch Inhalte nachzuladen. Und das auch noch ohne an  Sicherheitsschranken zu stossen.

Api-Call
Leider habe ich kein richtiges Wort für diese Methode und wir nannten sie immer intern die Apicall-Methode. Darum will ich auch bei diesem Namen bleiben. Sie ist simple wie genial, erfordert jedoch auch eine gewissen Umstellung der Daten. Die Idee ist, dass per JavaScript dynamisch JavaScript Dateien nachgeladen werden. So wird bei Bedarf einfach ein Skript-Tag eingebunden. Dieses JavaScript Code Stück enthält dann die Daten. Diese müssen nur in einer speziellen Form verfasst sein. Man könnte direkt eine JSON ablegen und danach pollen. Doch einfacher geht es, wenn man einen Funktionsaufruf erstellt und dieser die Daten als Parameter enthält. Man kann da beliebig komplex werden. Allerdings hat diese Methode ein paar gravierende Nachteil gegenüber Ajax. Es fehlen die Informationen zum Netzwerkstatus. Man kann also nicht mit absoluter Sicherheit sagen, ob eine Ressource fehlt. Doch da kann man sich grob behelfen. Mit dieser Methode kann man nun auch von anderen Diensten nur mittels JavaScript Daten einlesen, sofern diese den apicall unterstützen. Das ganze ohne einen Serverdienst, der als Proxy fungiert.

Was brauchen wir dafür?
Nicht viel. Wir sollten zuvor 2 Funktionen erstellen, die das Handling machen und können dann loslegen  Daten einzulesen. Die Daten können von dynamischen oder statische Server stammen. Die Daten müssen allerdings aufbereitet werden. Aber man gewöhnt sich schnell dran und vorallem wenn dynamische Programme diese Dateien erstellen, kann man dies schnell erledigen lassen.
Damit wir etwas Error-Handling betreiben habe ich noch eine dritte Funktion hinzugefügt. Die man aber auch weglassen kann. Damit die Kommunikation zwischen den Funktionen einfach gehalten werden kann und wir nicht extra eine Klasse definieren müssen, legen wir auch eine globale Variable an. Also eine Variable direkt im Skriptbereich. Ein komplexerer Variante, aber immer noch reine Funktionen findet man in der http://directpaylink.com/javascript/basics.js

Die JavaScipt Funktionen
var system = new Object();

function apicall(url, onSuccess, onError, onErrorTimeout, urlid) {
  if (!system)
    system = {};
  if (!system['dscript'])
    system['dscript'] = {'id':1, 'cb':{}, 'urls':{}};  
  var id = system["dscript"]["id"];
  system["dscript"]["cb"][id] = {"url": url, 
"onSuccess": onSuccess, "onError": onError, 
"time": new Date().getTime()};
  var refurl = url;
  if (!urlid)
    urlid = refurl
  system["dscript"]["urls"][urlid] = id; // für die statischen URLs
  var head    = document.getElementsByTagName("head")[0];
  var script  = document.createElement('script');
  script.id   = 'obj_dscript_'+id;
  script.type = 'text/javascript';    
var srcurl = url;
  if (srcurl.indexOf("?")<1)
    srcurl += "?"      
  script.src  = srcurl+"&cbf=RS_APIDispatcher&cbid="+id;
  var d = new Date();
  script.src += '&t='+d.getTime();
  head.appendChild(script);
  var timeout = 5000; // 5 sekunden
  if (onErrorTimeout)
    timeout = onErrorTimeout; 
  var errorcheck = setTimeout("RS_APIErroLoadCheck('"+id+"')", timeout);
  system["dscript"]["cb"][id]['errorcheck'] = errorcheck;    
  system["dscript"]["id"]++;
}   
function RS_APIDispatcher(id, result) {
  if (id == 0 && system["dscript"]["urls"][id])
    id = system["dscript"]["urls"][id];
  if (!document.getElementById('obj_dscript_'+id))
    return false;
  if (system["dscript"]["cb"][id])
    system["dscript"]["cb"][id]['dontkill'] = true;
  if (system["dscript"]["cb"][id] && system["dscript"]["cb"][id].errorcheck)  
    clearTimeout(system["dscript"]["cb"][id].errorcheck);
  var old = document.getElementById('obj_dscript_'+id);
  if (old != null) {
    old.parentNode.removeChild(old);
    delete old;
  }
  var oobj = null;
  if(typeof result == 'function')
    result = result();
  else if(typeof result == 'object') 
    oobj = result; 
  var obj = {"responseText": result, "object": oobj};
// errorload could have killed it already
if (system["dscript"]["cb"][id]) system["dscript"]["cb"][id].onSuccess(obj); 
delete(system["dscript"]["cb"][id]);   
}
function RS_APIErroLoadCheck(apicallid){                            
  if (!system["dscript"]["cb"][apicallid])
    return false;
  var objekt = system["dscript"]["cb"][apicallid];
if (system["dscript"]["cb"][apicallid]['dontkill'])
    return false;
  // immernoch da, also wahrscheinlich fehler aufgetreten 
  if (objekt.onError)
    objekt.onError(apicallid); 
  delete(system["dscript"]["cb"][apicallid]);
}

Erklärungen zu dem Code
Die erste Funktion ist der eigentliche Aufruf. Diese prüft ob die globale Variable existiert und deklariert gegebenenfalls eine. Genauso werden dann spezielle Variablen angelegt, damit der Apicall, weitere Informationen hintelegen kann. Hier ist natürlich eine Klasse bestimmt einfacher und angenehmer. 
Um statische Inhalte einzulesen, gibt man die Variable urlid mit an. Diese wird dann durch die eingeladene JavaScript Datei und darin durch den JavaScript Funktionsaufruf, als Parameter übergeben, so dass man dann die Antwort identifizieren kann. Bei dynamischen Antworten, kann der Server die entsprechenden Parameter setzen, so dass die urlid nicht nötig ist. Dann wird im Header ein Node erzeugt und die Datei eingelesen. Passiert natürlich asynchron. Damit man erkennen kann, ob ein Fehler beim Einlesen passiert ist, zum Beispiel, weil die Datei nicht vorhanden ist, wird eine Timer gesetzt. Der Standardwert ist auf 5 Sekunden gesetzt, das sollte langen, um auch bei langsamen Verbindungen nicht zu früh abzubrechen und gleichzeitig nicht zu spät den Fehler zu erkennen.
Sobald die Datei eingelesen ist, wird der darin enthaltene Code ausgeführt. Darum sollte dieser Code am besten auch den Funktionsaufruf RS_APIDispatcher(id, result) aufrufen. Als Parameter enthalten dann die URLID und als RESULT das entsprechende Ergebnis. Man sollte wissen, was man als Ergebnis erwartet. Es kann auch neben einem JSON auch eine Funktion sein. Diese wird dann auch gleich aufgerufen. So eine Art Callback. So kann man auch vom Server aus, bzw aus der Datendatei eine Funktion erzwingen. Am besten man erstellt ein JSON als result. Das kann man dann in der Callback-Funktion auswerten. Die Fehlerbehandlungsfunktion ist simple. Sollte diese aufgerufen werden, prüft diese ob nicht die Datei eingeladen wurde. Falls nicht, geht sie von einem Fehler aus und entfernt die Variablen zu diesem Apicall.


Die Datendatei
Die Statische Daten-JavaScript-Datei könnte folgenden Inhalt haben.

RS_APIDispatcher("buchdaten/autor", {'name':'detleff egge', 'titel':'mein buch'});


Beispiel Aufruf

var url = "http://api.domain.com/datendatei.js";
apicall(url,
function(h) {
alert(h.object.name);
  }, 
function(h){alert("error");}, 
10000,
"buchdaten/autor"
);


Fazit
Ist diese Methode einmal eingebunden, kann man auch ohne dynamische Server, ein hohes Mass an Dynamik und Flexibilität erreichen. Sind dynamische Server im Einsatz, muss man auf denen die Ausgabe erst implementieren, aber das ist recht einfach. Der Aufruf erfolgt mit dem Namen der Callback-Funktion und der im JavaScript verwalteten ID. So könnte ein dynamisches Skript diese Daten setzen und dann den Inhalt senden.
Diese Apicall-Methoden werden auch von RapidShare und DirectPayLink unterstützt und erlauben somit eigene Applikationen auf HTML und JavaScript Basis.

Dienstag, 19. April 2011

Effizientes betreiben von Portalen

Worum geht es?
In diesem Beitrag wird eine Vorgehensweise aufgezeigt, die zum Einen sehr kostengünstig im Unterhalt ist und zum anderen extrem viele User bedienen soll. Dabei versuche ich grundsätzliche Überlegungen anzuwenden, um den Bedarf zu erkennen und auch die Notwendigkeit von dynamischen Inhalten zu identifizieren. Dieser Beitrag verlangt eine gewisse Grundkenntnis der Materie. Sie kann nicht als generelle Lösung angesehen werden, doch bietet sie in den meisten Fällen eine interessante Vorgehensweise. Hier wird ganz klar eine abweichende Struktur von Webseiten mit Content gewählt und dadurch bedingt sie auch eine etwas breitere Wissensbasis in Webentwicklung und Server-Knowledge.

Warum weiss ich etwas darüber?
Ich habe von je her immer mit sehr vielen Daten und deren Bereitstellung im Netz zu tun gehabt. Sei es die Entwicklung von Shoplösungen für über 150.000 Produkte mit mehr als 1.000 Hersteller damals schon mit PHP3 über einem Web-Abrechungstool für einen grossen Internetzugangsprovider, der alleine pro Tag 20 Millionen Datensätze angesammelt hat bis hin zu RapidShare Entertainment, die eine Portalseite bereitstellten auf der täglich 500.000 User die Inhalte nutzen.

Diese Problemstellungen sollte alle sehr kostengünstig erstellt werden und darüber hinaus wollte ich immer wert auch Einfachheit legen. Einfach zu warten, einfach zu skalieren, einfach an Ressourcenbedarf.
Hier half mir sehr gut andere Ansätze zu wählen und das Wissen aus den anderen Bereichen, die manchmal einem reinen Programmierer fehlen, da er zu tief in der Materie gefangen ist.

Die Idee
Es gilt einen Plattform zu schaffen, die von vielen User besucht werden soll. Der Traffic soll im Rahmen bleiben, die Server sollen so unkompliziert wie möglich sein, damit ein schneller Wechsel auf andere Systeme und Provider möglich ist. Die Ausfallsicherheit sollte unterstützt werden und das Ganze soll natürlich sehr schnell beim Endkunden wirken. Die Daten werden in einer Datenbank erfasst und der Enduser kann diese, nach Freigabe ins System durch den Verfasser, lesen.

Grundlegende Gedanken
Es gibt sehr viele herangehensweisen. Oft wird eine Lösung gewählt, dass man eine Sprache wählt, um hier eine Einfachheit zu bringen. Doch diese "Faulheit" wird oft sehr teuer erkauft. So benötigt man viele Server um die dynamischen Skripte ablaufen zu lassen. Unter Umständen erhöht sich das Risiko, durch das Einsetzen der Skriptsprachen oder der Server ist sehr schwer und kann nicht eben mal neu gestartet werden bei einem Problem. Auch hier gibt es endlose Möglichkeiten.

Grundlegende Erklärungen
Was ist das schnellste, was wir im Web liefern können? Klar, die statischen Inhalte. Wenn der Webserver, die Anfrage verarbeitet und analysiert hat, kann er den nächsten Prozess anwerfen. Dabei geht er folgender Massen vor. Ist die Anfrage direkt für mich oder für einen Interpreter? Geht es zu einem Interpreter, weckt er den und sendet die Anfrage weiter. Dieser startet, meist müssen noch einige Variablen gesetzt werden und dann lädt er die Ressourcen ein. Interpretiert diese und startet den Ablauf. Ist nun auch eine Datenbankabfrage involviert, muss auch hier erstmal die Verbindung hergestellt werden. Dabei spielt es keine Rolle ob man persistente Verbindungen oder dergleichen nutzt, grundsätzlich muss die Datenbankserver-Verbindung hergestellt oder die bestehende Verbindung initialisiert werden. Nachdem nun alles abgearbeitet wurde, wird der erzeugte Ausgabetext an den Webserver zurück gegeben. Dieser sendet nun die Daten an den Client. Zeitintensive und Ressourcenintesive Operationen sind somit der Einsatz von Interpreter und andere nachgelagerte Helfersysteme. Das Einfachste ist somit wenn man in der Lage ist nur statische Inhalte, am besten noch in den Arbeitsspeicher ausgelagert auszuliefern.

Grundlegende Analyse des Systems
Hier muss  man sich die Applikation fertig vorstellen. Durschspielen, was erfasst werden soll und was gelesen werden soll. Oft ist es so, dass das Schreiben der Informationen nicht so oft passiert und das Lesen der Daten den Hauptteil der Applikation darstellt. Nun ist die Frage, ob das Erstellen der Applikation aus dynamischen Skripten entstehen sollte? Eigentlich kann man mindestens 2 Teile ausmachen. Einen schreibenden und einen Lesenden, der nicht dynamisch sein muss. Oft wird für das Lesen nicht einmal eine Zugangskontrolle benötigt. Warum sollte man hier nun Skripte einsetzen und Datenbankabfragen erstellen, für immer die gleichen Daten? Man ermittelt als Bestandteile, die auch rein statisch sein könnten. Dabei grob nur nach den Bereichen gehen und nicht schon auf den Inhalt direkt eingehen. Sprachen und zeitgesteuerte Analysen sind auch statisch. Oft sind Teile statisch realisierbar, die man nie vermutet hätte. Ganz klar ist das aber teils mit einem höheren Programmieraufwand verbunden, aber das Result rechtfertigt dies alle mal.

Die Aufteilung und Realisierung
Nachdem wir nun die Aufteilung gemacht habe und uns für eine Skriptsprache entschieden haben, können wir den serverseitigen Teil erstellen. Wir nehmen PHP und erstellen die Skripte zum Erfassen der Datensätze, Administration (Login, Rechte, etc) und zum Erstellen der statischen Inhalte. Unser PHP Skript erzeugt zu keiner Zeit HTML welches zum Arbeiten angezeigt wird. Dieser Vorgang hat auch den enormen Vorteil, dass wir die Serverkomponente beliebig austauschen könne. So könnten man um Performance zu erzeugen, auch die fertige Serverkomponente komplett in C inklusive dem Webserver realsieren und laufen lassen. Die Enduser-Seite erstellen wir in HTML. So kommunizieren unsere unabhängigen System mittels einer API. Auch hier der grosse Vorteil, dass ein Austauschen des Anzeigessystems komplett unabhängig vom Server statt finden kann.

Der Serverteil
Unser Skript erhält mittels API calls die Befehle zum Arbeiten. So reduzieren wir die eigentliche Arbeit auf den Server, denn für den anzeigenden Bereich nutzen wir statische Dateien. Somit realisiert unser Server nur die Anfragen und Antwortet auch sehr kurz mit JavaScript Code. Dieser wird dann im Client interpretiert. Dazu mehr später. Wir implementieren, die Einbindung der Datenbank und für den Administrator eine Verwaltung: User verwalten (anlegen, editieren, löschen), Beiträge verwalten (anlegen, editieren, löschen).
Dazu kommt dann die Loginprüfung und die Beitragsverwaltung für den einzelnen Benutzer.
Eventuell werden einige automatisierte Aktionen benötigt, wie das automatische Freigeben von Beiträgen, diese kann man auch wunderbar implementieren und später entweder per HTTP-Request oder über einen Consolen Aufruf starten. Ein Cronjob einrichten und fertig ist die Sache. Sobald eine Beitrag fertig ist speichert der Server nicht nur in der Datenbank, sondern auch auf eine Datei mit dem Inhalt. Diese Datei ist
in einem speziellen Format, so dass der Client diese per JavaScript Call einlesen kann und den Inhalt interpretieren kann. Hierzu gibt es verschiedene Herangehensweisen. Eine von mir bevorzugte werde ich in späteren Beiträgen erläutern. Vorerst kann könnte man AJAX einsetzen.

Passwortschutz für Verzeichnisse und Dateien
Grundsätzlich sollte man alles einfach halten, dass heisst nicht, dass das Erstellen einfach ist, sondern, dass wenige Komponenten eingesetzt werden und ein schnelles Protieren auf Backup oder Skalierserver möglich ist. Was könnten wir machen, wenn wir Dateien haben die gesichert sein sollten. Hier erstmal ein Mini-Ausflug in HTTPS. Die SSL Verbindung wird zum Server gemacht. Hierbei stellt der Client erstmal die Verbindung her, bevor er preis gibt, was er vom Server möchte. Man tauscht Schlüsselinformationen auf, so dass eine verschlüsselte Verbindung entstehen kann. Nachdem diese Verbindung steht, fragt der Client die Dateien an. Somit ist sogar der Request der Datei samt Pfad verschlüsselt.
Hier ist der Ansatz ausgelagert. Man könnte 2 oder mehr Schlüssel (zufällige alphanumerische Zeichenfolgen erstellen; also wie Login und Passwort). Diese Schlüssel werden wir um Verzeichnisse zu erstellen. Der Server sollte die Indexe nicht listen, aber um sicher zu gehen, legen wir in jedes Verzeichnis einfach eine Dateie ab die vom Server in der Regel interpretiert wird. Diese Datei muss natürlich schon im vorgelagerten Ordner liegen, da sonst der Ordner aufgelistet wird. Genauso kann man auch nur einzelne Dateien schützen, ist jedoch dann nicht so einfach bei einem Wechsel der Schlüssel alle betroffenen Dateien anzupassen. Deshalb empfehle ich einen Ordner, der ist schnell umbenannt. Diese Methode hat gegenüber HTACCESS auch den Vorteil, dass sie Webserver und Dateisystem unabhängig ist. Also ideal zum portieren.

Die Ausgabe, bzw die Enduser Seite
Der Enduser bekommt eine HTML-Seite. Diese wird mittels JavaScript die nötigen Daten holen, aufbereiten und anzeigen. Somit ist die Performance auf den Client ausgelagert. Die Serverkomponente muss nur sicherstellen, dass die Daten geschickt aufbereitet statisch vorliegen. Der Aufbau der eigentlichen Webapplikation erfolgt mittels Clientseitigem Skript und Nachladen von Elementen in den laufenden HTML Code. So muss serverseitig kein Skript angeworfen werden und keine Datenbank durchforstet werden. Die Applikation könnte eine statische Datei einlesen, welche die Kategorien der Beiträge enthält und diese auflisten. Wenn diese Daten angezeigt werden sollen, wird nach dem gleichen Prinzip wiederum eine Datei eingelesen, welche die Inhalte einliest. Der eigntliche Beitrag, kann ebenfalls in einer Datei ausgelagert sein, so dass der Datenaustausch schnell ist, da nur wenige benötigte Daten gesendet werden. Hier ist auch ein grosser Vorteil, dass die Daten keine Design Elemente enhalten und das Design der Seite ansich durch andere Dateien gesteuert wird. Mehrsprachigkeit, kann genauso realisiert werden, da man das komplette Design auch über statische Dateien einlesen kann. Das ganze bringen wir mittels JavaScript (.innerHTML oder Nodes) im Browser zur Anzeige.

Zu beachten und Überlegungen
Bei dieser Methode existieren unter Umständen sehr viele Dateien auf dem Server. Hier sollte man vorher die Masse an Dateien überdenken und ggf die Order gleich in 1.000 Schritte füllen. Bei Datendateien zum Beispiel könnte man pro Ordner immer 1.000 Objekte speichern und die nächsten in tiefer gelegene Ordner.
Also wenn der Datensatz zum Beispiel die ID: 123456789 hat, könnte der Speicherort sein: d/123/456/89/datensatz.js. Auch hier ist anzuraten, dass die Datendatei nicht Bestandteil der ID ist, so hat man gleich einen Container für weitere Infos, wie Screenshots und dergleichen. Der Zugriff einer einzelnen Datei geht immer sehr schnell, das Listing jedoch von Ordner die sehr viele Dateien enthalten, kann unter Umständen auch abbrechen. Mit der tausender-Regel sollten kaum Probleme auftreten, die ist performant genug und bietet auch ausreichend Kapazitäten. Die Serverkomponente wird nun nicht mehr so stark belastet und man kann einige statische Auslieferungsserver betreiben, während der dynamische Server alleine sein kann und unter Umständen auch nicht mal im Internet. So könnte nach dem Erstellen der Dateien, ein anderer Job diese Dateien auf die statischen Server kopieren. Hier hat man zwar eine Verzögerung, jedoch ist diese heutzutage gering. Nachteil ist hierbei, dass sehr viele Dateien im Voraus erstellt werden müssen und vieles ist redundant. Doch da diese durch den Server erstellt werden, sollte dies nicht schwerwiegend sein. Ein manuelles Eingreifen ist nur bedingt noch möglich und mit viel Aufwand verbunden. Aber gerade einige Listen ändern sich sehr selten und da kann man optimieren mit speziellen Cronjobs, die dann die Daten bei Leerlauf oder dergleichen abarbeiten.

Aus der Praxis
Wir haben damals die RapidGames.com und die dazugehörigen RapidMusic, RapidMovies nach dem gleichen Prinzip erstellt. Ein Server im Office war für die dynamischen Inhalte zuständig und die erzeugten Dateien wurden auf die statischen Server verteilt. Das lief so hervorragend, dass unser statischer Backserver eigentlich nie zum Einsatz kam. Auch ein Loadbalancing war nie nötig, bis zu dem Tag, an dem scheinbar unser Provider doch mehr Kunden aufnahm als verkraftbar. Wir haben damals einen statischen Webhosting Vertrag für ca. 15 CHF gehabt und damit auch 500.000 User pro Tag versorgt. Günstiger geht es kaum noch. Zumal die Lösung durch eine einfache index.html Datei sofort skalierbar war, die dann Anfragen an andere statische Server hätte weiterleiten können. Nicht mal Zugriff auf den Server ist dafür nötig. Sollte der Andrang so gross sein, dass selbst die Hits zuviel sind, kann man DNS Load-Balancing einsetzen. Einfach weitere IPs zum Domain-Eintrag ergänzen. Keep it simple. Klar dass dies nicht immer die saubersten Lösungen sind, aber bis her immer die unkompliziertesten und effektivsten. Man sollte sich immer Out-of-the-Box denken und sich die Mittel ansehen und sich fragen, wie kann ich mit den bestehenden Mittel das Ergebnis erreichen?

Saso Nikolov