Filtern des DataSnap-Byte-Streams

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu DataSnap-Client-Anwendung


Die Kommunikation zwischen einem DataSnap-Client und einem DataSnap-Server kann durch Filter abgefangen werden. Jeder Filter kann Transformationen mit dem Byte-Stream ausführen, wie etwa Verschlüsselung und/oder Komprimierung; der Byte-Stream kann von mehr als einem Filter abgefangen werden, und so wird die Ausgabe des einen zur Eingabe für den nächsten Filter. Die Filter werden dem Byte-Stream während des Entwurfs hinzugefügt (oder programmiert), indem die Eigenschaft Filters der Transportkomponenten des DataSnap-Servers, wie Datasnap.DSTCPServerTransport.TDSTCPServerTransport gesetzt werden.

Die Filter stehen während des Entwurfs zur Verfügung, wenn sie in einem bei RAD Studio registrierten Package vorhanden sind. Der Filter muss in einem Package integriert sein, und das Package muss in Delphi installiert sein. Die Unterstützung durch den Server zur Entwurfszeit aktiviert den Filter, so dass er im Filterlisten-Editor angezeigt wird. Die Unterstützung durch den Client zur Entwurfszeit aktiviert während des Entwurfs eine Verbindung über TSQLConnection.

Es ist nicht nötig, Filter auf der Client-Seite zuzuordnen, weil sie automatisch auf der Grundlage eines Handshake-Protokolls zwischen Client und Server instantiiert werden. Daher muss der Client-Code die Filter registrieren, bevor eine Verbindung zu einem gefilterten Server hergestellt wird, entweder durch Hinzufügen des Unit-Namens zur uses-Klausel oder bereits früher, z.B. bei der Initialisierung.

Hinweis: Daten-Explorer kann keine Verbindung zu Servern mit nativen Codefiltern herstellen, weil DataExplorer verwaltete Clients verwendet.

Hinweis: Sie können dieses Tutorial verfolgen, indem Sie das Video: Delphi Labs - Episode 3, von Paweł Głowacki anschauen.

Definieren eines Filters

Ein Filter sollte die Klasse TTransportFilter erweitern, und die Implementierung muss mindestens eine ID, die den Filter eindeutig identifiziert, und zwei Methoden bereitstellen: ProcessInput und ProcessOutput.

  public
    function ProcessInput(const Data: TBytes): TBytes; override;
    function ProcessOutput(const Data: TBytes): TBytes; override;
    function Id: UnicodeString; override;

Die Verarbeitungsmethoden sind zueinander invers: das Ergebnis der einen Methode wird als Eingabe an die andere übergeben und erzeugt die Anfangseingabe.

Jede Verbindung instantiiert einen Filter, daher müssen die Verarbeitungsfunktionen nicht Thread-sicher sein; lokale Variablen können beispielsweise verwendet werden, setzen aber keinen statusbehafteten Zustand für eine Instanz voraus.

Mit dem Standardkonstruktor ohne Parameter wird eine Filterinstanz instantiiert. Damit die Client-Instanzen kompatibel mit den Server-Instanzen sind, könnten zusätzliche Parameter erforderlich sein. Parameterwerte können zwischen Filtern auf dem Server und dem Client ausgetauscht werden. Das ist beispielsweise bei einer Implementierung eines symmetrischen Verschlüsselungsfilters erforderlich, wenn ein Speicherort für den Verschlüsselungsschlüssel übergeben werden muss.

Alle Parameter werden als Paare (Name, String) bereitgestellt. Die Namen können mit der Methode GetParameters zurückgegeben und die Werte mit GetParameterValue und SetParameterValue abgefragt oder geändert werden.

  protected
    function GetParameters: TDBXStringArray; override;
  public  
    function GetParameterValue(const ParamName: UnicodeString): UnicodeString; override;
    function SetParameterValue(const ParamName: UnicodeString; const ParamValue: UnicodeString): Boolean; override;

In einigen Fällen müssen alle Parameter oder eine Untermenge davon während des Entwurfs geändert werden; die Namen können mit der Methode GetUserParameters bereitgestellt werden.

  protected
    function GetUserParameters: TDBXStringArray; override;

Hinweis: Die Parameternamen, die von dieser Methode nicht zurückgegeben werden, sind während des Entwurfs nicht sichtbar oder nicht bearbeitbar.

Registrieren eines Filters

Ein Filter muss bei dem Singelton TTransportFilterFactory registriert werden. Es wird empfohlen, einen Filter in den Abschnitten initialization und finalization einer Unit zu registrieren, aber die Registrierung kann auch während der Initialisierung in der Benutzeranwendung vorgenommen werden.

Das folgende Codefragment registriert den Komprimierungsfilter:

initialization
  TTransportFilterFactory.RegisterFilter(TTransportCompressionFilter);

finalization
  TTransportFilterFactory.UnregisterFilter(TTransportCompressionFilter);

Der Verschlüsselungsfilter

Mit dem Verschlüsselungsfilter werden DataSnap-Byte-Streams verschlüsselt. Der Verschlüsselungsfilter arbeitet sowohl auf der Serverseite als auch auf der Client-Seite. Im Folgenden wird das Verhalten des Verschlüsselungsfilters beschrieben.

Serverseite:

  • Sowohl die Komponente Datasnap.DSTCPServerTransport.TDSTCPServerTransport als auch die Komponente Datasnap.DSHTTP.TDSHTTPService verfügen über die Eigenschaft Filters.
  • Wenn Sie die Filter-Eigenschaft auswählen, können Sie im angezeigten Dialogfeld einen neuen Filter hinzufügen. Für die Eigenschaft FilterId können Sie PC1 oder RSA auswählen.
  • Beim PC1-Verschlüsselungsfilter enthält die Eigenschaft Properties den Key-Wert, der für die Verschlüsselung verwendet werden soll. Beim RSA-Filter enthält die Eigenschaft Properties eine Liste mit drei Eigenschaften: UseGlobalKey, KeyLength und KeyExponent.

Client-Seite:

  • Die Eigenschaft Driver der TSQLConnection-Komponente hat eine Filters-Eigenschaft.

Auf diese Weise wird bei der Ausführung des Clients/Servers die Kommunikation zwischen beiden verschlüsselt.

Weitere Hinweise

Bei der Verwendung des Verschlüsselungsfilters mit DataSnap-Client/Serveranwendungen muss Folgendes berücksichtigt werden:

  • Die Datenverschlüsselung ist für schmale Clients nicht verfügbar.
  • Wenn der Server einen Verschlüsselungsfilter verwendet, der Client aber nicht, dann fügt der Client den Filter automatisch hinzu.
  • Wenn der Client einen Verschlüsselungsfilter verwendet, der Server aber nicht, dann verwirft der Client seinen Filter und verwendet ihn nicht.

Der Komprimierungsfilter

Der Komprimierungsfilter basiert auf ZLib und stellt Komprimierungsfunktionen für DataSnap-Byte-Streams bereit. Der Komprimierungsfilter arbeitet sowohl auf der Serverseite als auch auf der Client-Seite.

Die Komponente Datasnap.DSTCPServerTransport.TDSTCPServerTransport und die Komponente Datasnap.DSHTTP.TDSHTTPService verfügen über die Eigenschaft Filters. Hier fügen Sie einen neuen Filter hinzu, indem Sie die Eigenschaft FilterId auf ZLibCompression setzen. Für den Komprimierungsfilter können Sie in Properties auch Eigenschaften festlegen.