Einführung in CSharp Silverlight-DataSnap-Konnektoren für mobile Geräte

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Einführung in DataSnap-Konnektoren für mobile Geräte


Dieses Thema dient als Leitfaden für die Erzeugung und Verwendung des C#-Silverlight-DataSnap-Proxy bei der mobilen Windows Phone 7-Entwicklung. Der C#-Silverlight-Proxy unterstützt dieselben Datentypen wie DataSnap. Zur Kapselung dieser DBX- und Delphi-Typen wurden spezielle C#-Klassen erstellt. Deren Verwendung entspricht der in Delphi.

Auf Anforderung erzeugt der DataSnap-REST-Server die zum Aufruf der Methoden auf dem Server verwendete Proxy-Klasse und sendet diese. Dies entspricht weitgehend der Proxy-Erzeugung, die Ihnen wahrscheinlich bereits vertraut ist, umfasst aber zudem das Komprimieren des Proxy und aller abhängigen Dateien sowie das Senden dieser zip-Datei an den Anforderer.

Weitere Informationen über diesen Prozess finden Sie unter Einführung in DataSnap-Konnektoren für mobile Geräte.

Herunterladen der C#-Silverlight-Proxy-Dateien von einem DataSnap-REST-Server

Zunächst müssen Sie sich eine Kopie von Win32ProxyDownloader.exe aus dem Verzeichnis \bin Ihrer Produktinstallation beschaffen. Diese Datei und die Beschaffung einer Kopie davon wird im Thema Einführung in DataSnap-Konnektoren für mobile Geräte ausführlicher behandelt.

Das Download-Programm ist ein einfaches Hilfsprogramm zur Unterstützung der Ermittlung des Proxy und anderer für die Kommunikation mit dem Server erforderlicher Dateien auf dem Server.

Für das Download-Programm müssen Sie die folgenden Parameter angeben:

  • -language (erforderlich): Gibt die mobile Plattform und Sprache des angeforderten Proxy an. Verwenden Sie für Windows Phone 7 csharp_silverlight.
  • -protocol: Gibt das zu verwendenden Verbindungsprotokoll an: http oder https. Die Vorgabe ist http.
  • -host: Gibt den Port und den Hostnamen oder die IP-Adresse an, zu der verbunden werden soll. Vorgabe ist localhost mit Port 80. Wenn ein anderer Name oder Port benötigt wird, muss der Name voll qualifiziert sein und die durch Doppelpunkt (":") getrennte Portnummer enthalten.
  • -output: Gibt den Ordner an, in den die Proxy-Dateien heruntergeladen werden sollen. Wird diese Angabe weggelassen, wird der aktuelle Ordner verwendet.

Im folgenden Beispiel werden die meisten der oben beschriebenen Parameter verwendet:

 C:\Win32ProxyDownloader.exe -language csharp_silverlight -host 127.0.0.1:8080 -output C:\test

Nach Ausführung des Download-Programms, werden die C#-Silverlight-Proxy-Dateien in den angegebenen Ausgabeordner kopiert. Dazu zählen die folgenden Dateien:

  • JSON-Analysebibliothek (.dll)
  • Statische für den Proxy erforderliche C#-Quelldateien
  • DSProxy.cs, der erzeugte Proxy

Die Hauptdatei ist DSProxy.cs, die die Klasse deklariert, die alle auf dem Server definierten Methoden enthält.

Verwendung der DSProxy-Klasse

Der folgende Code zeigt die vom Server erzeugte Datei DSProxy.cs (C#). Der Code enthält eine TServerMethods1-Klasse, die die Servermethoden kapselt. Der Server hat nur eine Methode (EchoString), und die C#-Klasse TServerMethods1 implementiert die Methode entsprechend. Der Proxy-Generator erzeugt den gesamten Code für die Verbindung zum Server und für die Ausführung der Methoden automatisch. Siehe den folgenden C#-Code für die Methode EchoString:

 using System;
 using System.Threading;
 
 namespace Embarcadero.DataSnap.WindowsPhone7
 {
   public class DSProxy
   {
     public class TServerMethods1 : DSAdmin
     {
       public TServerMethods1(DSRESTConnection Connection, ExceptionCallback ExCal) : base(Connection, ExCal)
       {
       }
 
       private DSRESTParameterMetaData[] TServerMethods1_EchoString_Metadata;
       private DSRESTParameterMetaData[] get_TServerMethods1_EchoString_Metadata() {
         if (TServerMethods1_EchoString_Metadata == null) {
           TServerMethods1_EchoString_Metadata = new DSRESTParameterMetaData[] {
               new DSRESTParameterMetaData("Value", DSRESTParamDirection.Input, 
                                                     DBXDataTypes.WideStringType, "string"),
               new DSRESTParameterMetaData("", DSRESTParamDirection.ReturnValue, 
                                               DBXDataTypes.WideStringType, "string"),
           };
         }
         return TServerMethods1_EchoString_Metadata;
       }
 
       /**
        * @param Value [in] - Type on server: string
        * @return result - Type on server: string
        */
       public delegate void EchoStringCallback(String Result);
 
       public void EchoString(String Value, EchoStringCallback callback = null, ExceptionCallback ExCal = null)
       {
         DSRESTCommand cmd = getConnection().CreateCommand();
         cmd.setRequestType(DSHTTPRequestType.GET);
         cmd.setText("TServerMethods1.EchoString");
         cmd.prepare(get_TServerMethods1_EchoString_Metadata());
         InternalConnectionDelegate EchoStringDel = () => {
           if (callback != null) {
             try {
               callback.DynamicInvoke(cmd.getParameter(1).getValue().GetAsString());
             } catch (Exception ex) {
               if (ExCal != null) 
                 getConnection().syncContext.Send(new SendOrPostCallback(x => 
                    ExCal.DynamicInvoke(ex.InnerException)), null);
               else 
                 getConnection().syncContext.Send(new SendOrPostCallback(x => 
                   BaseExCal.DynamicInvoke(ex.InnerException)), null);
             }
           }
         };
         cmd.getParameter(0).getValue().SetAsString(Value);
         getConnection().execute(cmd, this, EchoStringDel, ExCal);
       }
     }
   }
 }

Der erste Schritt bei der Verwendung der Proxy-Klasse umfasst das Erstellen und Einrichten einer Verbindung zu dem Server. Die Klasse DSRESTConnection kapselt alle für die Verbindung zum Server erforderlichen Eigenschaften und Methoden. Erstellen Sie die Verbindung, und konfigurieren Sie die Eigenschaften wie folgt:

 DSRESTConnection connection = new DSRESTConnection();
 connection.setHost("hostname");
 connection.setPort(portnumber);
 connection.setProtocol("http");
  • Die Eigenschaft host gibt den Hostnamen oder die IP-Adresse an.
  • Die Eigenschaft port gibt den Port an, über den der Server empfängt.
  • Die Eigenschaft protocol gibt das für die Verbindung zu verwendende Protokoll an: http oder https.

Zum Remote-Aufruf der Servermethoden erstellen Sie einfach die Proxy-Klasse, übergeben die Verbindung und rufen dann die folgende Methode auf:

 DSRESTConnection connection = new DSRESTConnection();
 connection.setHost("localhost");
 connection.setPort(8080);
 connection.setProtocol("http");
 
 DSProxy.TServerMethods1 Proxy = new DSProxy. TServerMethods1(connection, ExceptionCallback);
 
 Proxy.EchoString("teststring", (String Result) =>
 {
    // ...
 }, ExceptionCallback);
 
 public void ExceptionCallback(Exception e)
 {
    // ...
 }

Beispiel einer Servermethode mit einem var-Parameter

Das folgende Beispiel zeigt den Code, der erzeugt wird, wenn Ihre Servermethode einen var-Parameter enthält oder mehrere Ergebnisse zurückgibt. Dies ist der Delphi-Code für die Servermethode:

 function TServerMethods1.VarParamTest(var Value: string): string;
 begin
   Value := StrUtils.ReverseString(Value);
   Result := Value;
 end;

Und das ist der erzeugte Proxy-Code zum Aufrufen dieser Servermethode:

 private DSRESTParameterMetaData[] TServerMethods1_VarParamTest_Metadata;
 private DSRESTParameterMetaData[] get_TServerMethods1_VarParamTest_Metadata()
 {
   if (TServerMethods1_VarParamTest_Metadata == null) {
     TServerMethods1_VarParamTest_Metadata = new DSRESTParameterMetaData[] {
       new DSRESTParameterMetaData("Value", DSRESTParamDirection.InputOutput, 
                                            DBXDataTypes.WideStringType, "string"),
       new DSRESTParameterMetaData("", DSRESTParamDirection.ReturnValue, 
                                      DBXDataTypes.WideStringType, "string"),
     };
   }
   return TServerMethods1_VarParamTest_Metadata;
 }
 
 /**
  * @param Value [in/out] - Type on server: string

Beachten Sie bitte, dass die Methode eine Instanz von VarParamTestReturns zurückgibt. Diese Sonderklasse enthält Informationen über var-Parameter (in/out) sowie das Ergebnis. Das folgende Beispiel zeigt, wie die Methode aufgerufen wird und die Ergebniswerte gelesen werden:

 Proxy. VarParamTest ("Hello, World!", 
   (DSProxy.TServerMethods1.VarParamTestReturns Result) => {
      Debug.WriteLine(Result.Value);
      Debug.WriteLine(Result.returnValue);
   }
 );

Sowohl der neue Wert des übergebenen Parameters als auch der Ergebniswert sind in der Result-Instanz enthalten. Der Wert für Result.Value ist "!dlroW ,olleH", und Result.returnValue ist "Hello, World!".

Verwenden von Heavyweight-Callbacks

Mit Heavyweight-Callbacks können DataSnap-Server fast verzögerungsfreie Benachrichtigungen an REST-Clients senden. Ein Client kann eine Callback-Funktion für ein bestimmtes, auf dem Server vorhandenes Thema registrieren. Bei Aktualisierung dieses Themas erhält der Client dann eine Benachrichtigung. Dies ist natürlich eine sehr vereinfachte Beschreibung dessen, was Heavyweight-Callbacks ausführen, sollte aber an dieser Stelle ausreichen.

Der erste Schritt bei der Verwendung von Callbacks in Ihren Anwendungen umfasst das Erstellen einer benutzerdefinierten Callback-Klasse, die von der abstrakten Klasse DBXCallback abgeleitet ist und die abstrakte Methode Execute überschreibt. Im Folgenden finden Sie eine Beispielimplementierung dieser Klasse:

 public class MyCallback : DBXCallback {
   public override TJSONValue Execute(TJSONArray params) {
     Debug.WriteLine(Params.ToString());
     return new TJSONTrue();
   }
 }

Die Klasse DSClientCallbackChannelManager verwaltet die Callbacks des Client. Sie stellt Methoden für die Registrierung und Deregistrierung der Callbacks und für das Schließen einzelner oder aller Callbacks bereit.

Der Konstruktor für DSClientCallbackChannelManager akzeptiert 3 Parameter:

  1. DSRESTConnection gibt die Serververbindungsinformationen an
  2. Ein String, der den Namen des Serverkanals enthält, bei dem die Registrierung erfolgen soll
  3. Ein String, der die ID (eindeutig für den Server) des Managers enthält
 DSCallbackChannelManager mngr = 
     new DSCallbackChannelManager(Connection, "chname", DSCallbackChannelManager.getNewManagerID());

Im folgenden Beispiel wird zunächst eine Callback-Funktion registriert und diese dann an denselben Kanal gesendet, bei dem sie registriert ist:


 public void testCallbacks(){
 
        DSAdmin admin = new DSAdmin(Connection, ManageExceptionCallback);
    mngr = new DSCallbackChannelManager(Connection," chname",DSCallbackChannelManager.getNewManagerID());
    mngr.registerCallback("mycb01", new MyCallback(), () =>
    {
 	admin.BroadcastToChannel("chname", new TJSONString("This is a broadcast"),(bool b) =>
         {
           mngr.closeClientChannel();
         });  
 
 }
 
 public void ManageExceptionCallback(Exception e)
 {
    // ...
 }

Der erste Parameter für die Methode registerCallback ist eine ID für die Callback-Funktion (eine für den Client-Kanal eindeutige ID). Der zweiter Parameter ist die eigentliche, zu registrierende Callback-Instanz, und der dritte ist eine Delegatmethode, die bei Abschluss der Registrierung aufgerufen werden soll.

Der obige Code zeigt die Registrierung einer neuen Instanz der Klasse MyCallback auf dem Server, der über den Kanal chname empfängt. Nach erfolgreicher Registrierung ruft der Client BroadcastToChannel auf und sendet den String "This is a broadcast" an alle Callbacks (einschließlich sich selbst), die über den Kanal chname empfangen.

Der dritte Parameter für den BroadcastToChannel-Aufruf ist ein Delegat, der aufgerufen wird, wenn der Aufruf vom Server zurückgegeben wird. Dieser Parameter enthält einen booleschen Wert, der angibt, ob der Server die Senden-Anforderung erfolgreich behandeln konnte. Der obige Code schließt dann in dieser verschachtelten Delegatdeklaration den Kanalmanager, so dass keine Aussendungen mehr empfangen werden.

Siehe auch