Filtrage du flux d'octets DataSnap

De RAD Studio
Aller à : navigation, rechercher

Remonter à Application Client DataSnap


La communication entre un client DataSnap et un serveur DataSnap peut être interceptée par une suite de filtres. Chaque filtre peut effectuer des transformations sur le flux d'octets, telles que l'encryptage et/ou la compression. Le flux d'octets peut être intercepté par plusieurs filtres, avec la sortie d'un filtre devenant l'entrée du filtre suivant. Les filtres sont attachés au flux d'octets à la conception (ou codés), en définissant la propriété Filters des composants de transport du serveur DataSnap tels que Datasnap.DSTCPServerTransport.TDSTCPServerTransport.

Les filtres sont disponibles à la conception s'ils sont présents dans un package enregistré avec RAD Studio. Le filtre doit être intégré dans un package qui doit être installé dans Delphi. Le support à la conception côté serveur permet au filtre d'être visible dans l'éditeur de la liste des filtres. Le support à la conception côté client active la connexion à la conception au moyen de TSQLConnection.

Il n'est pas nécessaire d'associer des filtres côté client, étant donné qu'ils sont automatiquement instanciés selon un protocole de transmission entre le client et le serveur. Par conséquent, il est important que le code client enregistre les filtres avant d'établir la connexion à un serveur filtré, en ajoutant le nom de l'unité à la clause uses ou à une étape initiale, telle que l'initialisation.

Remarque : L'explorateur de données n'est pas capable d'établir la connexion à des serveurs avec des filtres de code natif car DataExplorer utilise un client managé.

Remarque : Vous pouvez suivre le tutoriel en observant la vidéo : Delphi Labs - Episode 3, by Paweł Głowacki.

Définition d'un filtre

Tout filtre doit étendre la classe TTransportFilter et l'implémentation doit fournir au minimum un ID qui l'identifie de façon unique, et les deux méthodes suivantes : ProcessInput et ProcessOutput.

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

Les méthodes de traitement sont l'inverse de l'autre : le résultat d'une méthode passé en entrée de l'autre méthode produit l'entrée initiale.

Chaque connexion instancie un filtre. Ainsi, il n'est pas nécessaire que les fonctions de traitement soient "thread safe". Par exemple, les variables locales peuvent être utilisées, mais ne prennent pas un état "state-full" pour une instance.

Le constructeur sans paramètre par défaut est utilisé pour instancier une instance de filtre. Des paramètres supplémentaires peuvent être nécessaires afin que les instances client soient compatibles avec les instances serveur. Les valeurs de paramètres peuvent être échangées entre les filtres côté serveur et les filtres côté client. Par exemple, cela peut s'avérer nécessaire si l'emplacement de la clé d'encryptage doit être passé dans le cas de l'implémentation d'un filtre d'encryptage symétrique.

Tous les paramètres sont exposés sous forme de paires (nom, chaîne). Leurs noms peuvent être renvoyés par le biais de la méthode GetParameters et leurs valeurs peuvent être interrogées ou changées en utilisant GetParameterValue et SetParameterValue.

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

Dans certains cas, tous les paramètres ou un sous-ensemble de ces paramètres doivent être modifiés à la conception. Leurs noms peuvent être fournis par la méthode GetUserParameters.

  protected
    function GetUserParameters: TDBXStringArray; override;

Remarque : Les noms des paramètres qui ne sont pas renvoyés par cette méthode ne sont pas visibles ou modifiables à la conception.

Enregistrement d'un filtre

Un filtre doit être enregistré avec le singleton TTransportFilterFactory. Il est recommandé d'enregistrer un filtre par le biais des sections initialization et finalization de l'unité, mais il peut être codé dans une phase d'initialisation de l'application utilisateur.

Voici l'extrait de code enregistrant le filtre de compression disponible :

initialization
  TTransportFilterFactory.RegisterFilter(TTransportCompressionFilter);

finalization
  TTransportFilterFactory.UnregisterFilter(TTransportCompressionFilter);

Le filtre d'encryptage

Le filtre d'encryptage est utilisé pour encrypter un flux d'octets DataSnap. Le filtre d'encryptage fonctionne aussi bien côté serveur que côté client. Le comportement du filtre d'encryptage est décrit dans les lignes suivantes.

Côté serveur :

  • Les composants Datasnap.DSTCPServerTransport.TDSTCPServerTransport et Datasnap.DSHTTP.TDSHTTPService ont tous deux une propriété Filters.
  • Lors de la sélection d'une propriété de filtre, vous pouvez ajouter un nouveau filtre dans la boîte de dialogue qui apparaît. Dans la propriété FilterId, vous pouvez choisir PC1 ou RSA.
  • En cas d'utilisation du filtre d'encryptage PC1, la propriété Properties contient la valeur Key à utiliser pour l'encryptage. En cas d'utilisation du filtre RSA, la propriété Properties contient une liste de trois propriétés, UseGlobalKey, KeyLength et KeyExponent.

Côté client :

De cette façon, quand vous exécutez réellement le client/serveur, la communication entre eux sera encryptée.

Notes supplémentaires

Plusieurs choses sont à prendre en compte lors de l'utilisation du filtre d'encryptage avec des applications DataSnap client/serveur :

  • L'encryptage des données n'est pas disponible avec les clients légers.
  • Si le serveur a un filtre d'encryptage mais que le client n'en a pas, le client ajoutera automatiquement le filtre.
  • Si le client a un filtre d'encryptage mais que le serveur n'en a pas, le client supprimera alors son filtre et ne l'utilisera pas.

Le filtre de compression

Le filtre de compression est basé sur ZLib et fournit des capacités de compression pour les flux d'octets DataSnap. Le filtre de compression fonctionne à la fois côté serveur et côté client.

Les composants Datasnap.DSTCPServerTransport.TDSTCPServerTransport et Datasnap.DSHTTP.TDSHTTPService ont une propriété Filters. C'est là où vous ajoutez un nouveau filtre définissant la propriété FilterId sur ZLibCompression. Vous pouvez aussi spécifier les propriétés du filtre de compression en définissant la propriété Properties.