DataSnap-Anwendungsbeispiel
Nach oben zu Mehrschichtige Anwendungen erstellen - Index
Die DataSnap-Technologie ermöglicht, Client-Serveranwendungen zu erstellen, die über das Internet, das lokale Netzwerk oder den lokalen Host kommunizieren.
Das folgende Beispiel demonstriert die Verwendung von DataSnap beim Erstellen einer lokalen Client-Serveranwendung. Die Client- und die Serveranwendungen sind in Delphi implementiert. Nach dem Festlegen der Verbindung zwischen dem Client und dem Server mit DataSnap, kann der Client Methoden aufrufen, die auf dem Server implementiert sind.
Serveranwendung erstellen
- Wählen Sie im Hauptmenü Datei > Neu > VCL-Formularanwendung - Delphi.
- Platzieren Sie die folgenden Komponenten aus der Kategorie DataSnap-Server der Tool-Palette auf dem Formular:
Jetzt sollte Ihre Serveranwendung etwa folgendermaßen aussehen:
Die Komponente TDSServer ist das logische Herz der DataSnap-Serveranwendung. Sie enthält die Methoden Start und Stop zum Starten und Stoppen des Servers und außerdem die sehr praktische Eigenschaft AutoStart. Standardmäßig ist der Wert der Eigenschaft AutoStart auf True gesetzt, so dass der Server beim Anwendungsstart automatisch startet. Sie benötigen nur eine TDSServer-Komponente pro Serveranwendung.
Die Komponente TDSTCPServerTransport implementiert einen Multithread-TCP-Server, der eingehende Client-Verbindungen über mehrere Threads empfängt. Diese Komponente hat keine Ereignisse. Die Eigenschaft Port gibt den zu verwendenden TCP-Port an. Per Vorgabe ist dies der Port 211.
Die Komponente TDSServerClass repräsentiert eine Serverklasse.
Der DataSnap-Server erstellt automatisch Instanzen der Serverklassen und gibt diese auch automatisch frei. Die Instantiierung einer Serverklasse wird von der Eigenschaft LifeCycle der TDSServerClass-Komponente gesteuert. Die Eigenschaft LifeCycle kann einen der drei folgenden Werte haben: Server, Session und Invocation.
Wenn LifeCycle auf Server gesetzt ist, erstellt der DataSnap-Server eine Instanz einer Serverklasse, die von allen mit der Serveranwendung verbundenen Clients verwendet wird. Dies repräsentiert ein “Singleton”-Muster. Gehen Sie bei der Verwendung der Server-Lebensdauer mit Sorgfalt vor, weil Ihre Serverklassenimplementierung Thread-sicher sein muss. Auch weiterhin ist Vorsicht geboten, weil es möglich ist, dass mehrere Threads gleichzeitig auf dieses Singleton-Objekt zugegreifen.
Der Vorgabewert für LifeCycle ist Session. Das bedeutet, dass der DataSnap-Server eine Instanz einer Serverklasse für jeden verbundenen Client erstellt.
Der dritte mögliche Wert für die Eigenschaft LifeCycle ist Invocation. Eine Serverklasseninstanz wird für jeden von einem Client eingehenden Methodenaufruf erstellt und freigegeben. Der Status einer Serverklasse wird zwischen Methodenaufrufen nicht beibehalten.
Führen Sie die folgenden Schritte aus, um die drei Komponenten miteinander zu verknüpfen:
- Wählen Sie die TDSServerClass-Komponente auf dem Formular aus.
- Setzen Sie die Eigenschaft Server der TDSServerClass-Komponente auf den Namen Ihrer TDSServer-Komponente.
- Wählen Sie die TDSTCPServerTransport-Komponente auf dem Formular aus.
- Setzen Sie die Eigenschaft Server der TDSTCPServerTransport-Komponente auf den Namen Ihrer TDSServer-Komponente.
Fügen Sie Ihrem Projekt eine neue Unit hinzu, indem Sie im Hauptmenü Date > Neu > Unit - Delphi wählen. Diese Unit enthält die Implementierung der Klassen, die in der Client-Anwendung verwendet werden sollen. Der folgende Quelltext repräsentiert beispielsweise die Implementierung einer Klasse namens MyClass, die eine Methode (die Summe zweier Double-Zahlen) enthält:
unit MyClass; interface uses Classes; type {$METHODINFO ON} TMyClass = class(TComponent) function Sum(const A, B: Double): Double; end; {$METHODINFO OFF} implementation { TMyClass } function TMyClass.Sum(const A, B: Double): Double; begin Result := A + B; end; end.
Um die Klasse festzulegen, die aus der Client-Anwendung aufgerufen werden soll, definieren Sie das Ereignis OnGetClass für die Komponente TDSServerClass:
- Wählen Sie die TDSServerClass-Komponente auf dem Formular aus.
- Aktivieren Sie im Objektinspektor die Registerkarte Ereignisse.
- Doppelklicken Sie auf den Wert für das Ereignis OnGetClass.
- Geben Sie den folgenden Code ein (ersetzen Sie TMyClass mit dem Namen der Klasse, die Sie im vorherigen Schritt definiert haben):
PersistentClass := TMyClass;
Wenn Sie dieses Ereignis nicht implementieren, wird sofort nach dem Start der Anwendung die Exception TDBXError mit der Meldung OnGetClass-Ereignis nicht gesetzt, oder Ereignis hat keine Klassenreferenz bereitgestellt ausgelöst. Das Ereignis OnGetClass hat das Argument PersistentClass, das per Referenz übergeben wird. Im Ereignisbehandlungscode muss der Programmierer PersistentClass eine Klassenreferenz auf eine Serverklasse zuordnen (wie im obigen Beispiel). Dies ist wahrscheinlich das wichtigste Konzept, das bei der DataSnap-Architektur verstanden werden muss. Eine Klassenreferenz wird einer PersistentClass zugeordnet und nicht einer Objektreferenz.
Fügen Sie die zuvor definierte Unit der Liste mit den von der Serveranwendung verwendeten Units hinzu.
Die Serveranwendung ist implementiert.
Client-Anwendung erstellen
- Um die Client-Anwendung in derselben Projektgruppe wie die Serveranwendung zu erstellen, klicken Sie Ihre Projektgruppe in der Projektverwaltung mit der rechten Maustaste an und wählen Neues Projekt hinzufügen, oder wählen Sie aus dem Hauptmenü Projekt > Neues Projekt hinzufügen.
- Das Dialogfeld Objektgalerie wird geöffnet. Wählen Sie die Kategorie Delphi-Projekte und dann VCL-Formularanwendung.
- Fügen Sie in das Client-Formular die Steuerelemente ein, die für die Daten und das Ergebnis (Beschriftungen, Eingabefelder und eine Schaltfläche zum Berechnen des Ergebnisses) benötigt werden.
- Fügen Sie eine TSQLConnection-Komponente aus der Kategorie dbExpress der Tool-Palette hinzu.
- Setzen Sie für die TSQLConnection die folgenden Eigenschaften:
- Driver - Datasnap (aus der Perspektive des Clients sieht dieser Provider wie eine Verbindung zu einer Datenbank aus, stellt aber tatsächlich die Konnektivität zu den DataSnap-Servern her).
- LoginPrompt - False (optional, um zu verhindern, dass das Anmelde-Dialogfeld jedes Mal angezeigt wird, wenn der Client eine Verbindung zum Server herstellt).
Das Client-Formular sollte nun etwa folgendermaßen aussehen:
- 6. Der wichtigste Schritt beim Entwickeln der Client-Serveranwendung mit DataSnap ist das Erstellen des Interface, das den Prototyp aller auf dem Server implementierten Funktionen enthält.
Gehen Sie dazu folgendermaßen vor:
- Wählen Sie das Serverprojekt aus, indem Sie in der Projektverwaltung auf den Namen des Projekts doppelklicken.
- Wählen Sie aus dem Hauptmenü Start > Ohne Debugger ausführen.
- Wenn der Server ausgeführt wird, wählen Sie das Client-Projekt, indem Sie in der Projektverwaltung auf dessen Namen doppelklicken.
- Setzen Sie die Eigenschaft Connected der TSQLConnection-Komponente auf True.
- Klicken Sie die TSQLConnection-Komponente auf dem Client-Formular mit der rechten Maustaste an, und wählen Sie DataSnap-Client-Klassen erzeugen. Ihrem Client-Projekt wird eine neue Unit hinzugefügt, die Informationen über die auf dem Server implementierten Klassen und alle in diesen Klassen enthaltenen Methoden enthält.
- Speichern Sie die neue Unit, und fügen Sie sie der Liste mit den von der Client-Anwendung verwendeten Units hinzu.
- 7. Verwenden Sie nun die gewünschten Methoden in der Client-Anwendung. Implementierten Sie beispielsweise das Ereignis OnClick für die TButton-Komponente, und rufen Sie die Methode Sum aus der automatisch erzeugten Unit auf (wurde in dem Beispiel als MyClassClient gespeichert):
procedure TClientForm.CalculateClick(Sender: TObject); var Temp: TMyClassClient; A, B: Double; begin Temp := TMyClassClient.Create(SQLConnection1.DBXConnection); try A := StrToFloat(EditA.Text); B := StrToFloat(EditB.Text); EditResult.Text := FloatToStr(Temp.Sum(A, B)); finally Temp.Free; end;
Hinweis: Schließen Sie vor dem Beenden der Serveranwendung alle SQL-Verbindungen. DataSnap gibt keine Warnung über ausstehende Verbindungen aus. Der Server wird erst geschlossen, wenn keine Verbindungen mehr zu ihm bestehen. Das Schließen aller Client-Anwendungen löst das Problem nicht, weil die Delphi-IDE eine Verbindung zu dem Server automatisch öffnen und nach bereitgestellten Klassen und Methoden suchen kann.

