Vous êtes sur la page 1sur 65

Livre Blanc

DELPHI 2010 DATASNAP TOUTES VOS


DONNES... O VOUS VOULEZ
COMME
VOUS VOULEZ
Bob Swart

Bob Swart Training & Consultancy (eBob42)

Sige social
100 California Street, 12th Floor
San Francisco, California 94111

Sige EMEA
York House
18 York Road
Maidenhead, Berkshire
SL6 1SF, United Kingdom

Sige Asia-Pacific
L7. 313 La Trobe Street
Melbourne VIC 3000
Australia

Copyright 2009 Bob Swart (aka Dr. Bob - www.drbob42.com). Tous droits rservs.

Ce livre blanc couvre les nouveaux outils et fonctionnalits de larchitecture


Delphi 2010 DataSnap.

1.
1.1
2.
2.1.
2.1.1.
2.1.1.1.
2.1.1.1.1.
2.1.1.1.2.
2.1.1.1.3.
2.1.1.1.4.
2.1.1.1.5.
2.1.1.2.
2.1.2.
2.1.3.
2.1.4.
2.2.
2.2.1.
2.2.1.1.
2.2.1.2.
2.3.
2.3.1.
3.
3.1.
3.2.
3.2.1.
3.2.2
3.2.3.
3.2.4.
3.3.
3.4.
4.
4.1.
4.2.
4.3.
5.
5.1.
5.2.
5.3.
6.
6.1.
7.
7.1.
8.

Delphi 2010 DataSnap Toutes vos donnes O vous voulez


Comme vous voulez
1
Historique DataSnap
2
Exemple DataSnap Toutes vos donnes O vous voulez
3
Cibles Windows DataSnap Comme vous voulez
3
Exemple de serveur DataSnap
3
Groupe de projet multicible Formulaires VCL
5
ServerContainerUnitDemo
7
TDSServer
7
TDSServerClass
8
TDSTCPServerTransport
9
TDSHTTPService
9
TDSHTTPServiceAuthenticationManager
11
ServerMethodsUnitDemo
11
Groupe de projet multicible Console
12
Groupe de projet Multicible Service Windows
14
Mthodes serveur
14
Client DataSnap
16
Classes client DataSnap
18
Protocole de communication HTTP
19
Authentification HTTP
19
Dploiement serveur DataSnap
20
Dploiement client DataSnap
20
DataSnap et bases de donnes O vous voulez
21
TsqlServerMethod
23
TDSProviderConnection
24
Client TDSProviderConnection
25
Mises jour de base de donnes
26
Rconciliation des erreurs
27
Dmonstration de la rconciliation des erreurs
29
Dploiement Base de donnes DataSnap
30
Rutilisation des modules de donnes distants existants
31
Filtres DataSnap Les donnes comme vous voulez
31
Filtre ZlibCompression
32
Filtre Log
33
Filtre de cryptage
34
Cibles Web DataSnap Comme vous voulez (suite)
35
Cible Dbogueur dapplication Web
36
Cible ISAPI
37
Mthodes serveur, dploiement et clients
39
REST et JSON Comme vous voulez
43
Rappels (Callbacks)
43
DataSnap et .NET O vous voulez (suite)
44
Client WinForms
49
Synthse
52

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

1.

Historique DataSnap

Prcdemment connue sous le nom de MIDAS (Delphi 3), MIDAS II (Delphi 4) et


MIDAS III (Delphi 5), cette solution offrait un moyen de dvelopper de puissants
modules COM daccs distant aux donnes avec des fonctionnalits de connexion
TCP/IP, HTTP et (D)COM. Le nom DataSnap est apparu avec Delphi 6 et son
framework est rest relativement intact jusqu Delphi 2007.
Depuis Delphi 2009, une version rarchitecture de DataSnap est propose
supprimant les dpendances avec COM et introduisant un moyen plus lger pour
produire des objets et serveurs distants et connectivits client lorigine
uniquement avec des connexions TCP/IP mais avec la possibilit de construire
des clients .NET avec Delphi Prism 2009.
Delphi 2010 repose sur larchitecture DataSnap 2009 et en tend le framework
avec de nouvelles fonctionnalits : prise en charge de nouvelles cibles travers
deux nouveaux Assistants (Fiches VCL, Windows Service, Console et galement
cibles Web telles que ISAPI, CGI ou Dbogueur dapplication Web), protocoles de
transport HTTP(S), authentification HTTP, fonction de rappel client, support REST
et JSON, filtres de compression (dj intgrs) et cryptage.
1.1 Exemple DataSnap Toutes vos donnes O vous voulez
Je vous engage largement utiliser les dmonstrations et exemples fournis dans
ce livre blanc. Delphi prend en charge diffrents systmes de bases de donnes
(avec des technologies daccs telles que DBX4, dbGo for ADO, etc.). Pour
simplifier la manipulation des exemples, jutiliserai DBX4 avec BlackfishSQL
comme SGBDR avec la base de donnes employee.jds situe dans le rpertoire
C:\Documents and Settings\All
Users\Documents\RADStudio\7.0\Demos\database\databases\BlackfishSQL sous
Windows XP
ou
C:\Users\Public\Documents\ RAD
Studio\7.0\Demos\database\databases\BlackfishSQL sous Windows Vista ou
Windows 7.
Comme vous le verrez dans les copies dcran, jutilise le systme dexploitation
Windows 7 Professionnel pour les exemples et Windows Server 2008 Web Edition
pour le dploiement des serveurs DataSnap ISAPI.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

2. Cibles Windows DataSnap


Comme vous voulez
DataSnap 2010 prend en charge trois diffrentes cibles Windows : applications
Fiches VCL, applications Service et les applications Console. Dans cette section,
jenvisagerai les avantages, diffrences et meilleurs cas dutilisation de chacune
de ces cibles.
Nous construirons un serveur et un client DataSnap et couvrirons les composants
TDSServer, TDSServerClass, TDSTCPServerTransport, TDSHTTPService,
TDSHTTPWebDispatcher et TDSHTTPServiceAuthenticationManager, les
mthodes serveur personnalises et la classe TDSServerModule.
Nous aborderons diffrents protocoles de transport (TCP, HTTP) ainsi que leurs
effets et avantages respectifs potentiels. Les diffrentes options de dure de vie
des objets serveur DataSnap seront galement abordes (serveur, session et
invocation) avec leurs effets et des recommandations pratiques. Enfin, nous
aborderons certains enjeux de dploiement.

2.1. Exemple de Serveur DataSnap


Il existe deux assistants Serveur DataSnap dans le rfrentiel dobjets : un pour
les projets Windows, lautre pour les projets WebBroker qui doivent tre
hbergs sur un serveur Web tel que IIS (Internet Information Services).
Nous dbuterons par le premier.
Si vous dbutez avec Delphi 2010, vous trouverez les assistants Serveur
DataSnap dans le rfrentiel dobjets (Fichier | Nouveau | Autre). La catgorie
serveur DataSnap affiche trois icnes : Serveur DataSnap , Application
WebBroker DataSnap et Module serveur.

Effectuez un double-clic sur Serveur DataSnap (nous reviendrons ultrieurement


sur les deux autres) pour ouvrir la bote de dialogue suivante :

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

La premire partie de cette bote de dialogue permet de contrler la cible du


projet. Par dfaut il sagit dune application graphique VCL (avec un formulaire
principal) ; le second choix produit une fentre console idale pour tracer les
requtes/rponses (avec de simples dclarations writeln pour dmontrer ce qui
se passe rellement dans lapplication serveur). Ces deux types dapplications
sont idales pour des dmonstrations et dveloppements initiaux mais
finalement moins pratiques pour dployer une application serveur DataSnap. La
nouvelle architecture DataSnap ntant plus base sur COM, une connexion client
entrante ne permet pas de lancer une application serveur DataSnap. Par
consquent, pour manipuler les requtes client entrantes, le serveur DataSnap
doit dj tre oprationnel et en fonctionnement. En outre, si vous souhaitez
pouvoir traiter les demandes entrantes 24X7, lapplication serveur DataSnap doit
galement tre lance et oprationnelle en permanence. Pour une application
Fiches VCL ou Console, cela signifie quun compte doit tre logu sous Windows
pour excuter lapplication serveur DataSnap ce qui nest pas idal. Le
troisime choix est prfrable dans ce cas : une application de Service Windows
qui peut tre installe et configure pour tre automatiquement excute au
dmarrage de la machine (sans quil soit ncessaire que quelquun soit logu sur
la machine). Linconvnient dune application de service est que, par dfaut, elle
napparat pas sur le poste client et est galement un peu plus complexe
dboguer. Cependant, pour obtenir le meilleur des trois mondes, je dmontrerai
dans quelques instants comment crer un groupe projet pour une application
Serveur DataSnap Fiches VCL, Console et Windows Service partageant les
mmes mthodes serveur personnalises permettant ainsi de compiler (et
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

dployer) la mme application serveur pour trois cibles diffrentes en cas de


besoin.
La deuxime partie de la bote de dialogue permet de slectionner les protocoles
de communication. Par comparaison DataSnap 2009, il est dsormais possible
de choisir des communications et authentifications HTTP. Pour plus de flexibilit,
nous slectionnerons toutes les options pour pouvoir utiliser TCP/IP et HTTP pour
les communications et HTTP pour lauthentification.
La dernire partie est configure correctement par dfaut ; elle permet de
gnrer une classe de mthodes serveur et mme de choisir le type :
TPersistent, TDataModule ou TDSServerModule. Le dernier choix est le meilleur
car il active ds le dpart RTTI pour les mthodes (dans certaines circonstances
TDataModule ou ventuellement si vous nutilisez pas de jeux de donnes ni de
contrles non-visuels TPersistent peuvent suffire).
Le snippet suivant de DSServer.pas indique la relation entre TDSServerModule et
TProviderDataModule driv son tour de TDataModule.
TDSServerModuleBase = class(TProviderDataModule)
public
procedure BeforeDestruction; override;
destructor Destroy; override;
end;
{$MethodInfo ON}
TDSServerModule = class(TDSServerModuleBase)
end;
{$MethodInfo OFF}

En cas de doute, il convient de slectionner la classe TDSServerModule.

2.1.1. Groupe de projet multicible VCL FORMS


Comme indiqu, nous allons crer un groupe de projet serveur DataSnap
multicible. Nous dbuterons par lapplication Fiches VCL en slectionnant tous les
protocoles de communication.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Cette opration cre un nouveau projet dnomm par dfaut Project1.dproj


avec trois units, dnommes par dfaut ServerContainerUnit1.pas,
ServerMethodsUnit1.pas et Unit1.pas. Nous devons tout dabord slectionner
Fichier | Enregistrer le projet sous, pour indiquer des noms de fichiers plus
explicites : enregistrer Unit1.pas sous MainForm.pas, ServerContainerUnit1.pas
sous ServerContainerUnitDemo.pas, ServerMethodsUnit1.pas sous
ServerMethodsUnitDemo.pas et enfin Project1.dproj sous DataSnapServer.dproj.
Nous ajouterons dans un instant au groupe de projet lapplication Console et
lapplication Service. Tout dabord, revenons sur ce que nous venons de crer et
tentons de compiler le projet. Si vous compilez le projet DataSnapServer, vous
obtiendrez un message derreur (car nous avons renomm lunit gnre
ServerMethodsUnit1.pas). Le message derreur est donc caus par lunit
ServerContainerUnitDemo.pas qui contient lunit ServerMethodsUnit1 dans la
clause dutilisation de sa section dimplmentation (ligne 30), alors que
ServerMethodsUnit1.pas a t enregistr sous ServerMethodsUnitDemo. Pour
corriger ce problme, la clause doit tre modifie pour reflter ce changement de
nom. Si vous compilez nouveau, une erreur se produit alors la ligne 37 o
ServerMethodsUnit1 est utilis pour la classe TServerMethods1. Changez
galement ici ServerMethodsUnit1 en ServerMethodsUnitDemo pour que le projet
Serveur DataSnap puisse tre compil sans encombre.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

La section dimplmentation de lunit ServerContainerUnitDemo doit se


prsenter comme suit:
implementation
uses
Windows, ServerMethodsUnitDemo;
{$R *.dfm}
procedure TServerContainer1.DSServerClass1GetClass(
DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass);
begin
PersistentClass := ServerMethodsUnitDemo.TServerMethods1;
end;
end.

2.1.1.1. SERVERCONTAINERUNITDEMO

Longlet Design de lunit ServerContainerUnitDemo comporte cinq composants :


TDSServer, TDSServerClass, TDSTCPServerTransport (communication TCP/IP),
TDSHTTPService (communication HTTP) et
TDSHTTPServiceAuthenticationManager (authentification HTTP).

Les deux premiers composants sont toujours prsents ; les trois autres
dpendent naturellement des protocoles de communication optionnels
slectionns.

2.1.1.1.1. TDSSERVER
Le composant TDSServer na que quatre proprits : AutoStart, HideDSAdmin,
Name et Tag. La proprit AutoStart est paramtre par dfaut sur True, ce qui
signifie que le Serveur DataSnap dmarrera ds que le formulaire est cr. Dans
le cas contraire, il est possible dappeler manuellement la mthode Start la
mthode Stop peut toujours tre appele. La fonction Started permet de
dterminer si le Serveur DataSnap a dj dmarr.
Par dfaut la proprit HideDSAdmin est paramtre sur False. Dans le cas
contraire (True), les clients se connectant au Serveur DataSnap ne peuvent pas
appeler les mthodes serveur intgres de la classe TDSAdmin. Cette dernire
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

nest pas proprement parler une classe mais ses mthodes que nous pouvons
appeler sont documentes dans lunit DSNames :
TDSAdminMethods = class
public
const CreateServerClasses = 'DSAdmin.CreateServerClasses';
const CreateServerMethods = 'DSAdmin.CreateServerMethods';
const FindClasses = 'DSAdmin.FindClasses';
const FindMethods = 'DSAdmin.FindMethods';
const FindPackages = 'DSAdmin.FindPackages';
const GetPlatformName = 'DSAdmin.GetPlatformName';
const GetServerClasses = 'DSAdmin.GetServerClasses';
const GetServerMethods = 'DSAdmin.GetServerMethods';
const GetServerMethodParameters = 'DSAdmin.GetServerMethodParameters';
const DropServerClasses = 'DSAdmin.DropServerClasses';
const DropServerMethods = 'DSAdmin.DropServerMethods';
const GetDatabaseConnectionProperties = 'DSAdmin.GetDatabaseConnectionProperties';
end;

Le composant TDSServer a cinq vnements : OnConnect, OnDisconnect,


OnError, OnPrepare et OnTrace. Nous pouvons crire des gestionnaires pour ces
cinq vnements rpondant aux diffrentes situations (par exemple, en crivant
une ligne de texte dans un fichier journal).
Largument des vnements OnConnect, OnDisconnect, OnError et OnPrepare
est driv de TDSEventObject contenant des proprits pour les composants
DxContext, Transport, Server et DbxConnection. Le type TDSConnectEventObject
(utilis pour OnConnect et OnDisconnect) contient galement
ConnectionProperties et ChannelInfo.
TDSErrorEventObject inclut galement lexception ayant caus lerreur et
TDSPrepareEventObject les proprits pour MethodAlias et ServerClass que nous
souhaitons utiliser.
Largument du gestionnaire dvnements OnTrace est de type TDBXTraceInfo.
Remarquons que ce gestionnaire dvnements gnr OnTrace produit
galement des erreurs car les types TDBXTraceInfo et CBRType sont inconnus
du compilateur. Pour rsoudre ce problme, nous devons ajouter lunit
DBXCommon (pour le type TDBXTraceInfo) et lunit DBCommonTypes (pour
CBRType).

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Lors du gestionnaire dvnements OnConnect, nous pouvons examiner


ChannelInfo pour la connexion (par exemple en utilisant une fonction spcifique
LogInfo pour crire ces informations dans un fichier journal) :
procedure TServerContainer1.DSServer1Connect
(DSConnectEventObject: TDSConnectEventObject);
begin
LogInfo('Connect ' + DSConnectEventObject.ChannelInfo.Info);
end;

Et lintrieur de OnTrace, nous pouvons journaliser les contenus de TraceInfo.Message


pour obtenir une vision claire des oprations ralises par le serveur.
function TServerContainer1.DSServer1Trace(TraceInfo: TDBXTraceInfo): CBRType;
begin
LogInfo('Trace ' + TraceInfo.CustomCategory);
LogInfo(' ' + TraceInfo.Message);
Result := cbrUSEDEF; // action par dfaut
end;

Remarquons que ct client nous pouvons galement tracer la communication


entre client et serveur DataSnap en utilisant un composant TSQLMonitor
connect TSQLConnection (nous dmontrerons cette opration plus tard lors de
la construction du client pour ce Serveur DataSnap).
Exemple de trace :
17:05:55.492 Trace
17:05:55.496 read 136 bytes:{"method":"reader_close","params":[1,0]}
{"method":"prepare","params":[-1,false,"DataSnap.ServerMethod",
"TServerMethods1.AS_GetRecords"]}
17:05:55.499 Prepare

Comme vous pouvez le constater, TraceInfo.Message contient des informations


sur le nombre doctets et sur la mthode appele.

2.1.1.1.2. TDSSERVERCLASS
Le composant TDSServerClass est responsable dindiquer la classe ct serveur
utilise pour exposer les mthodes publies aux clients distants ( travers une
invocation de mthode dynamique).
La proprit Serveur du composant TDSServerClass pointe sur le composant
TDSServer. Lautre proprit importante en plus de Name et Tag est
LifeCycle paramtre par dfaut sur Session mais qui peut aussi prendre les
valeurs Server ou Invocation. Pour faire bref, Server, Session et Invocation
signifient qu'une instance de classe est utilise pour toute la dure de vie du
serveur, pour la dure de la session DataSnap ou simplement pour linvocation
de mthode. Session signifie que chaque connexion entrante obtiendra sa propre
instance de la classe serveur. Si vous choisissez Invocation, vous terminerez
avec une classe serveur sans-tat utile si vous souhaitez dployer une
application de serveur Web CGI (qui est galement sans tat et
charge/dcharge chaque requte) ; si vous passez Server, une seule
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

instance de classe serveur est partage par toutes les connexions et requtes
entrantes. Ce qui peut tre utile (par exemple, si vous souhaitez compter le
nombre de requtes) mais il faut sassurer que cela ne risque pas de causer des
problmes de threading (par exemple, lorsque de multiples requtes entrantes
doivent tre traites simultanment).
Le composant TDSServerClass a quatre vnements : OnCreateInstance,
OnDestroyInstance (instance cre/dtruite), OnGetClass et OnPrepare. Le
gestionnaire dvnements OnPrepare peut tre utilis pour prparer une
mthode serveur.
En cas dutilisation de Delphi 2009 ou de Delphi 2010 en plaant manuellement
le composant TDSServerClass dans un conteneur, nous devons implmenter
lvnement OnGetClass car nous devons spcifier quelle classe sera
dporte/distancie du serveur vers le client.
Cependant, les assistants DataSnap de Delphi 2010 implmentent
automatiquement le gestionnaire OnGetClass comme suit :
procedure TServerContainer1.DSServerClass1GetClass
(DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass);
Begin
PersistentClass := ServerMethodsUnitDemo.TServerMethods1;
end;

Remarquons quil sagit du code gnr que nous avons lgrement modifi en
renommant lunit ServerMethodsUnit1 pour lenregistrer sous
ServerMethodsUnitDemo.pas.

2.1.1.1.3. TDSTCPSERVERTRANSPORT
Le composant TDSTCPServerTransport est responsable de la communication
entre serveur et clients DataSnap en utilisant le protocole TCP/IP.
Le composant TDSTCPserverTransport dispose de cinq proprits importantes :
BufferKBSize, Filters (nouveau dans Delphi 2010), MaxThreads, PoolSize, Port et
Server.
La proprit BufferKBSize indique la dimension du buffer de communication (par
dfaut 32 Ko). La proprit Filters peut contenir une collection de filtres de
transport (couverts en dtail la section 4). La proprit MaxThreads permet de
dfinir le nombre maximal de threads (0 par dfaut signifiant pas de limite
maximale ). PoolSize peut tre mis en uvre pour activer des pools de
connexion et la proprit Port pour contrler le port TCP/IP utilis par le serveur
pour se connecter au client (si vous modifiez ce paramtre, vous devrez
galement le modifier par la suite dans le client DataSnap).
La proprit Serveur renvoie au composant TDSServer. Le composant
DSTCPServerTransport ne comporte aucun vnement.

2.1.1.1.4. TDSHTTPSERVICE
Le composant TDSHTTPService assure la communication entre le serveur
DataSnap et les clients DataSnap via le protocole HTTP.
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Il a 10 proprits (en plus de Name et Tag) : Active, AuthenticationManager,


DSHostname, DSPort, Filters, HttpPort, Name, RESTContext, Server et
ServerSoftware (lecture uniquement).
La proprit Active, qui indique si DSHTTPService coute les requtes entrantes,
peut tre paramtre sur True lors de la phase de conception ; cela empchera
toutefois lapplication serveur DataSnap de dmarrer en phase dexcution (en
effet, il ne peut y avoir plus dun seul composant DSHTTPService actif pour un
mme port et s'il en existe dj un au moment de la conception, il est impossible
den dmarrer un second en phase dexcution). Le meilleur moyen de dmarrer
TDSHTTPService est de paramtrer la proprit Active sur True dans le
gestionnaire dvnements OnCreate de TServerContainer :
procedure TServerContainer1.DataModuleCreate(Sender: TObject);
begin
DSHTTPService1.Active := True;
end;

La proprit AuthenticationManager est utilise pour dfinir le composant


gestionnaire prenant en charge lauthentification HTTP ; dans notre exemple, elle
renvoie au composant TDSHTTPServiceAuthenticationManager. Celui-ci est
dtaill au paragraphe 2.1.1.1.5.
Les proprits DSHostname et DSPort sont utilises pour dfinir le serveur
DataSnap auquel se connecter mais uniquement lorsque la proprit Serveur
nest pas paramtre. Dans la plupart des cas, il suffit pour y remdier de
connecter la proprit Serveur un composant TDSServer.
La proprit Filters peut contenir un ensemble de filtres de transport, dtaills au
paragraphe 4.
La proprit HttpPort est utilise pour dfinir le port auquel se connectera le
composant DSHTTPService pour couter les connexions entrantes. Notez que
cette valeur de port est fixe par dfaut 80, et doit tre modifie en cas de
dveloppement sur une machine quipe d'un serveur Web (par exemple, IIS),
puisque ce dernier utilise dj le port 80 et quil est donc impossible d'y
connecter le composant TDSHTTPService.
Les tentatives dexcution de lapplication feront apparatre un message derreur
qui pourra sembler peu comprhensible premire vue. La proprit
RESTContext dfinit l'URL contextuelle REST qui peut tre utilise pour appeler le
serveur DataSnap en tant que service REST. Par dfaut, RESTContext est
paramtr sur rest , ce qui signifie qu'il est possible dappeler le serveur
http://localhost/datasnap/rest/, comme nous le verrons dans la section 6,
portant sur les mthodes de rappel REST, JSON et client.
Enfin, la proprit Serveur devra renvoyer un composant TDSServer situ dans
le mme conteneur. Si vous ne souhaitez pas connecter la proprit Serveur,
vous pouvez utiliser les proprits DSHostname et DSPort pour vous connecter
au serveur DataSnap Server via TCP. Lorsque la proprit Serveur est
paramtre, les proprits DSHostname et DSPort sont ignores.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Le composant TDSHTTPService comporte cinq vnements : quatre vnements


lis REST et un vnement Trace.
Les vnements REST sont dtaills au paragraphe 6.
Lvnement OnTrace peut tre utilis pour suivre les appels du composant
DSHTTPService, comme le montre l'exemple suivant :
procedure TServerContainer1.DSHTTPService1Trace(Sender: TObject;
AContext: TDSHTTPContext; ARequest: TDSHTTPRequest;
AResponse: TDSHTTPResponse);
begin
LogInfo('HTTP Trace ' + AContext.ToString);
LogInfo(' ' + ARequest.Document);
LogInfo(' ' + AResponse.ResponseText);
end;

Notez que les informations HTTP Trace napparaissent que lorsque le client utilise
effectivement le protocole HTTP pour se connecter au serveur (et non le
protocole TCP/IP par dfaut).
Exemple de sortie de trace :
17:05:55.398 HTTP Trace TDSHTTPContextIndy
17:05:55.400 /datasnap/tunnel
17:05:55.403 OK

Ceci signifie que : AContext est paramtr sur TDSHTTPContextIndy, ARequest


est paramtr sur /datasnap/tunnel et AResponse est paramtr sur OK.

2.1.1.1.5. TDSHTTPSERVICEAUTHENTICATIONMANAGER
Le composant TDSHTTPServiceAuthenticationManager sera plac dans le
conteneur du serveur si l'option dauthentification du protocole de communication
HTTP a t coche. Bien entendu, il est toujours possible de le placer
manuellement dans le conteneur.
Le composant TDSHTTPServiceAuthenticationManager doit tre connect la
proprit AuthenticationManager dun composant TDSHTTPService.
Il comporte un seul vnement, OnHTTPAuthenticate, qui peut tre utilis pour
vrifier les informations dauthentification HTTP fournies au Serveur par le Client
DataSnap.
procedure TServerContainer1.DSHTTPServiceAuthenticationManager1HTTPAuthenticate
(Sender: TObject; const Protocol, Context, User, Password: string;
var valid: Boolean);
begin
if (User = 'Bob') and (Password = 'Swart') then
valid := True
else
valid := False
end;

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Bien entendu, cette routine de validation devra tre complte dune recherche
dans la base de donnes, par exemple partir dune version hache du mot de
passe. Pour les envois dinformations utilisateur et mot de passe (hach) du
client au serveur, lauthentification HTTP est facilite par lemploi du protocole
HTTPS sur une partie du transfert ; il est donc esprer quEmbarcadero
lajoutera la liste actuelle des protocoles HTTP et TCP/IP.
Le protocole HTTPS garantira que la connexion est scurise et que le paquet de
donnes est crypt et empchera tout programme de capter vos donnes
dutilisateur et mot de passe (haches). Consultez votre fournisseur de services
Internet ou votre Webmestre pour connatre les ventuelles possibilits HTTPS
de votre domaine cette mesure est fortement recommande (jutilise par
exemple https://www.bobswart.nl).
Une autre technique efficace applique par certaines applications serveur
DataSnap consiste crire les (tentatives) dauthentification HTTP dans un
fichier de log pouvant galement accueillir les donnes de Protocole et de
Contexte. Ceci peut savrer utile pour connatre lidentit des utilisateurs qui sy
connectent et de ceux qui tentent de sy connecter (par exemple, les fausses
tentatives de connexions destines accder au serveur DataSnap).

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

2.1.1.2. SERVERMETHODSUNITDEMO
Aprs ServerContainerUnitDema.pas, passons maintenant une autre unit
importante de la nouvelle application serveur DataSnap : lunit
ServerMethodsUnitDemo.pas. Dans la bote de dialogue New DataSnap Server,
nous avons spcifi la classe TDSServerModule utiliser comme anctre ; le type
TServerMethods1 est donc driv de TDSServerModule (qui est driv de
TDSServerModuleBase, lui-mme driv de TProviderDataModule, qui ajoute un
module de destruction Destroy et une procdure BeforeDestruction). Un
TProviderDataModule est driv dun TDataModule normal, et apporte des
fonctionnalits supplmentaires de collaboration avec des fournisseurs (ceci sera
dvelopp ultrieurement).
tant donn que lune des classes anctres de TServerMethods1 est
TDataModule, longlet de conception indiquera la zone concepteur pour un
module de donnes : les contrles non-visuels (par exemple, contrles daccs
aux donnes) pourront y tre placs. Nous verrons le placement des composants
d'accs aux donnes la section 3 ; dans limmdiat, nous laisserons la zone de
conception vide et continuerons dcouvrir comment ajouter des mthodes la
classe TServerMethods1.
Si vous ne souhaitez pas ajouter de cibles supplmentaires au groupe projet pour
une application DataSnap Console et/ou DataSnap Windows Service, vous
pouvez passer directement la partie 2.1.4, pour commencer implmenter les
mthodes serveur.

2.1.2. CONSOLE DE GROUPE PROJET MULTI-CIBLE


Retournons maintenant au groupe projet et ajoutons-lui une seconde cible :
lapplication Console. Cliquez avec le bouton droit sur le nud du groupe projet
et slectionnez Ajouter un nouveau projet. Dans le rfrentiel dobjets, allez dans
la catgorie Serveur DataSnap et double-cliquez sur licne Serveur DataSnap.
Slectionnez cette fois la cible Application Console dans la bote de dialogue
Nouveau serveur DataSnap.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Notez que quelles que soient les autres options slectionnes, vous rutiliserez
ServerContainerUnitDemo.pas et ServerMethodsUnitDemo.pas partir du projet
DataSnapServer dans tous les cas.
Cliquez sur OK pour gnrer le nouveau projet. L encore, ceci aboutira la
cration dun fichier Project1.dproj, ainsi que dun fichier
ServerContainerUnit2.pas et dun fichier ServerMethodsUnit2.pas. Cliquez avec le
bouton droit sur lunit ServerMethodsUnit2.pas dans le Gestionnaire de projets
et retirez-la du nouveau projet.
Conservez ServerContainerUnit2.pas pour linstant, elle servira copier une
mthode.
Enregistrez le projet dans DataSnapConsoleServer.dproj.
Si vous comparez le contenu de lunit ServerContainerUnitDemo.pas celui de
la nouvelle unit ServerContainerUnit2.pas (pour lapplication console), vous
constaterez que cette dernire inclut une procdure globale nomme
RunDSServer. Cette procdure globale nest utile que pour une application
Console ; vous devrez donc la copier/coller dans le code source du projet
DataSnapConsoleServer.dproj juste avant le dbut du bloc principal.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Loutil de contrle des erreurs signalera alors un certain nombre de problmes


qui peuvent tre rsolus en ajoutant lunit Windows la clause dutilisation de
DataSnapConsoleServer.dpr. DataSnapConsoleServer doit maintenant
ressembler ce qui suit :
program DataSnapConsoleServer;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
ServerContainerUnit2 in 'ServerContainerUnit2.pas'
{ServerContainer2: TDataModule};
procedure RunDSServer;
var
LModule: TServerContainer2;
LInputRecord: TInputRecord;
LEvent: DWord;
LHandle: THandle;
begin
Writeln(Format('Starting %s', [TServerContainer2.ClassName]));
LModule := TServerContainer2.Create(nil);
try
LModule.DSServer1.Start;
try
Writeln('Press ESC to stop the server');
LHandle := GetStdHandle(STD_INPUT_HANDLE);
while True do
begin
Win32Check(ReadConsoleInput(LHandle, LInputRecord, 1, LEvent));
if (LInputRecord.EventType = KEY_EVENT) and
LInputRecord.Event.KeyEvent.bKeyDown and
(LInputRecord.Event.KeyEvent.wVirtualKeyCode = VK_ESCAPE) then
break;
end;
finally
LModule.DSServer1.Stop;
end;
finally
LModule.Free;
end;
end;
begin
try
RunDSServer;
except
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end
end.

Trois nouvelles actions sont maintenant ncessaires et feront malheureusement


apparatre de nouveaux problmes dans loutil de contrle des erreurs : le projet
DataSnapConsoleServer utilise toujours lunit ServerContainerUnit2.pas, qui
doit donc tre retire. Pour cela, cliquez dessus avec le bouton droit et
slectionnez Retirer du projet. Cliquez ensuite avec le bouton droit sur le nud
DataSnapConsoleServer.exe, slectionnez Ajouter, choisissez
ServerContainerUnitDemo.pas ainsi que ServerMethodsUnitDemo.pas et ajoutezles au projet.
Toutes les rfrences TServerContainer2 seront alors signales comme erreur
de syntaxe. ServerMethodsUnitDemo.pas doit dfinir le type TServerContainer1 ;
par consquent, les problmes prcdemment indiqus peuvent tre rgls de la
manire suivante : renommez TServerContainer2 dans le code source entre
DataSnapConsoleServer et TServerContainer1 (trois emplacements au total).
Vous devriez ensuite tre en mesure de compiler le nouveau projet
DataSnapConsoleServer.dproj et le projet DataSnapServer.dproj original. Vous
pourrez alors partager les units ServerContainerUnitDemo.pas et
ServerMethodsUnitDemo.pas entre les deux cibles projets.

2.1.3. GROUPE PROJET MULTI-CIBLE WINDOWS SERVICE

Aprs le serveur DataSnap Fiches VCL et le serveur de console DataSnap, une


cible reste ajouter au groupe projet : lapplication DataSnap Windows Service.
Pour ajouter cette cible, cliquez avec le bouton droit sur le nud du groupe
projet, slectionnez Ajouter un nouveau projet et double-cliquez nouveau sur
licne Serveur DataSnap dans le dialogue Nouveaux lments. Choisissez
Application Service et slectionnez toutes les options de protocole de
communication (TCP/IP, HTTP et HTTP Authentication). Comme nous allons le
voir, le conteneur serveur dune application Service est lgrement diffrent de
celui dune application Fiches VCL ou Console ; assurez-vous donc de
slectionner, l encore, toutes les options de protocole de communication.
La bote de dialogue Nouveaux serveur DataSnap affiche alors un nouveau
projet, ainsi quune unit ServerContainerUnit et une unit ServerMethodsUnit.
Lunit ServerMethodsUnit est la mme que celle vue prcdemment et peut
donc tre retire du nouveau projet et remplace par le fichier
ServerMethodsUnitDemo.pas partag par les applications VCL Forms et Console
DataSnap.
En revanche, la nouvelle unit ServerCotainerUnit1.pas est diffrente : au lieu
dutiliser TDataModule pour placer TDSServer, TDSServerClass et les composants
de transport, la classe ainsi obtenue est drive de TService (qui contient les
composants DataSnap). De plus, quatre mthodes spciales y ont t ajoutes
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

pour implmenter les vnements Stop, Pause, Continue et Interrogate du


service :
type
TServerContainer3 = class(TService)
DSServer1: TDSServer;
DSTCPServerTransport1: TDSTCPServerTransport;
DSHTTPService1: TDSHTTPService;
DSHTTPServiceAuthenticationManager1: TDSHTTPServiceAuthenticationManager;
DSServerClass1: TDSServerClass;
procedure DSServerClass1GetClass(DSServerClass: TDSServerClass;
var PersistentClass: TPersistentClass);
procedure ServiceStart(Sender: TService; var Started: Boolean);
private
{ Private declarations }
protected
function DoStop: Boolean; override;
function DoPause: Boolean; override;
function DoContinue: Boolean; override;
procedure DoInterrogate; override;
public
function GetServiceController: TServiceController; override;
end;

En dautres termes, lunit ServerContainerUnitDemo.pas originale ne peut tre


partage avec le projet Windows Service, et ServerContainerUnit1.pas doit tre
renomm ServerContainerUnitServiceDemo.pas. Nous en profiterons, ce stade,
pour enregistrer le projet lui-mme dans DataSnapServiceServer.dproj.
Il est donc ncessaire de corriger la rfrence l'ancienne unit
ServerMethodsUnit2.pas dans ServerContainerUnitServiceDemo en la remplaant
par ServerMethodsUnitDemo.pas pour sassurer au moins que les mmes
mthodes serveur sont partages par les trois cibles.

2.1.4. METHODES SERVEUR


Maintenant que nous disposons dun ou de plusieurs projets DataSnap Server
partageant tous la mme unit ServerMethodsUnitDemo, il est temps dexaminer
les mthodes serveur plus en dtail.
Comme il est mentionn plus haut, la classe TServerMethod1 est lobjet serveur
DataSnap qui prsente les mthodes (via RTTI) exposes aux clients DataSnap.
Si vous avez slectionn loption Inclure les mthodes exemple , une mthode
exemple sera dj prsente dans la classe TServerMethods1 : la fonction
Echostring. Ajoutons-en une autre pour retourner lheure actuelle de la machine
serveur DataSnap. Pour cela, il suffit de modifier la dfinition de
TServerMethods1 en incluant deux mthodes publiques, comme il est montr cidessous :
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

type
TServerMethods1 = class(TDSServerModule)
private
{ Private declarations }
public
{ Public declarations }
function EchoString(Value: string): string;
function ServerTime: TDateTime;
end;

Limplmentation de la mthode ServerTime ne prsente pas de relle difficult et est tout


aussi rapide que la mthode EchoString de notre exemple :
function TServerMethods1.EchoString(Value: string): string;
begin
Result := Value;
end;
function TServerMethods1.ServerTime: TDateTime;
begin
Result := Now
end;

Nous pouvons maintenant compiler et excuter lapplication serveur. Si plusieurs


cibles projet ont t cres, la plus simple tester ce stade est le module
excutable DataSnapServer. En fonction de la version Windows et du niveau des
paramtres de scurit, une alerte de scurit Windows pourra safficher pour
signaler que le pare-feu Windows a bloqu certaines fonctionnalits de
lapplication DataSnapServer.

Ceci est d au fait que lapplication DataSnapServer est alors en mode dcoute
active des requtes entrantes via TCP/IP et HTTP. Elle agira alors comme un

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Cheval de Troie capable dcouter les requtes entrantes ; pour cela, cliquez
sur le bouton Autoriser laccs et poursuivez le dmarrage du serveur DataSnap.

2.2. CLIENT DATASNAP


Une fois que la premire dmonstration serveur DataSnap est oprationnelle et
en mode dcoute des requtes entrantes, il est temps de dvelopper un client.
Dans cette section, nous verrons comment se connecter au serveur partir dun
client et comment importer les mthodes en gnrant des classes serveur.
Assurez-vous que le serveur DataSnap est en excution avant de crer le projet
dapplication client DataSnap. Pour pouvoir alterner simplement entre les projets
serveur DataSnap et le projet client DataSnap en phase de conception, il suffit
dajouter le projet client DataSnap au mme groupe projet. Nimporte quel projet
peut tre un client DataSnap, mais pour cette dmonstration, nous utiliserons
une application Fiches VCL et lenregistrerons dans DataSnapClient.dpr (le
formulaire sera sauvegard dans ClientForm.pas). Lorsque la catgorie Serveur
DataSnap de la palette doutils contient les six composants (serveur) DataSnap,
la catgorie Client DataSnap ne contient pas les composants que nous devons
utiliser ce stade :

Les composants de la catgorie Client DataSnap sont les vieux composants


DataSnap, qui sont toujours utilisables ; nanmoins, cette approche nest pas
recommande pour utiliser DataSnap ce stade.
une exception prs, toutefois : le nouveau composant TDSProviderConnection,
qui peut tre utilis pour connecter un vieux serveur DataSnap un nouveau
client (comme nous le verrons au paragraphe 3.2).
Plutt que la catgorie Client DataSnap, nous examinerons la catgorie
dbExpress, contenant un nouveau composant TSQLServerMethod (remarquons
sur la capture dcran que ce nouveau composant est facilement identifiable
puisque son prfixe comporte TSql au lieu de TSQL, contrairement aux
composants dbExpress existants).

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Le composant TSqlServerMethod peut tre utilis pour appeler des mthodes


distantes partir dun serveur DataSnap, mais doit pralablement tre connect
au serveur DataSnap.
Ceci peut tre effectu laide dun composant TSQLConnection et non avec
lun des anciens composants TxxxConnection. Pour simplifier cette opration, le
composant TSQLConnection propose un nouveau nom de pilote dans la liste
droulante (DataSnap).
Il suffit donc de placer un composant TSQLConnection sur le formulaire
ClientForm et de paramtrer sa proprit Driver sur DataSnap. La proprit
Driver affiche alors un signe plus ( gauche du nom de proprit), et peut
tre dveloppe pour afficher lensemble des sous-proprits.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Remarque : si la proprit CommunicationProtocol nest pas renseigne, le


protocole TCP/IP est utilis par dfaut pour la connexion TSQL (et non le port
211 spcifi).
Par dfaut, BufferKBSize est paramtr sur 32 (Ko), et le Port sur 211
exactement comme pour le serveur. En pratique, il est recommand de choisir
un autre numro de port (aux niveaux serveur et client), car le 211 est
communment associ au port assurant la connexion aux serveurs DataSnap.
Le nom dhte, nom dutilisateur et mot de passe sont utiliss pour se connecter
au serveur DataSnap. Pour un test local, vous pouvez ventuellement
paramtrer HostName sur localhost, mais en rgle gnrale, il est possible de
saisir n'importe quel nom d'hte, nom DNS ou numro IP direct pour renseigner
cette proprit.
Assurez-vous de paramtrer la proprit LoginPrompt du composant
TSQLConnection sur False pour viter que la bote de dialogue de connexion ne
saffiche.
Aprs avoir renseign les proprits du pilote TSQLConnection, vous pouvez
paramtrer la proprit Connected sur True pour (tenter de) vous connecter au
serveur DataSnap. Notez que le serveur DataSnap doit tre en cours dexcution
au niveau serveur pour russir cette connexion !

2.2.1. CLASSES CLIENT DATASNAP


Aprs avoir vrifi que la connexion est possible, cliquez avec le bouton droit sur
le composant TSQLConnection et slectionnez loption Gnrer les classes client
DataSnap. Cette action gnrera une nouvelle unit, appele par dfaut Unit1,
avec une classe appele TServerMethods1Client (qui correspond au nom de la
classe de mthodes Serveur DataSnap au niveau serveur, complt de la partie
Client ). Enregistrez cette unit dans ServerMethodsClient.pas.
La dfinition de la classe TServerMethods1Client gnre sera la suivante :
type
TServerMethods1Client = class
private
FDBXConnection: TDBXConnection;
FInstanceOwner: Boolean;
FEchoStringCommand: TDBXCommand;
FServerTimeCommand: TDBXCommand;
public
constructor Create(ADBXConnection: TDBXConnection); overload;
constructor Create(ADBXConnection: TDBXConnection;
AInstanceOwner: Boolean); overload;
destructor Destroy; override;
function EchoString(Value: string): string;
function ServerTime: TDateTime;
end;

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Comme vous pouvez le constater, il existe deux constructeurs pour la classe


TServerMethods1Client class et un destructeur ; vous devriez galement
retrouver les deux mthodes serveur dfinies au niveau du serveur DataSnap.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Pour utiliser ces mthodes, ajoutez l'unit ServerMethodsClient la clause


dutilisation du formulaire Client, placez un composant TButton sur le formulaire
et crivez le code suivant dans le gestionnaire dvnements OnClick :
procedure TForm2.Button1Click(Sender: TObject);
var
Server: TServerMethods1Client;
begin
Server := TServerMethods1Client.Create(SQLConnection1.DBXConnection);
try
ShowMessage(DateTimeToStr(Server.ServerTime))
finally
Server.Free
end;
end;

Ce code gnrera linstance de TServerMethods1Client ; appelez ensuite la


mthode serveur ServerTime, puis supprimez nouveau le proxy du serveur
DataSnap.
En cliquant sur ce bouton, un message saffichera pour indiquer la valeur date et
heure du serveur, comme prvu.

Le lecteur est invit sexercer en appliquant cette mme procdure pour tester
la mthode EchoString.

2.2.1.1. PROTOCOLE DE COMMUNICATION HTTP


Comme nous lavons mentionn, TCP/IP est le protocole de communication par
dfaut du composant TSQLConnection. Ceci signifie galement que nous ne
retrouvons aucun des messages HTTP Trace (dfinis au point 2.1.1.1.4). Notez
toutefois que pour changer de protocole de communication, il suffit dindiquer
HTTP en tant que valeur de la sous-proprit CommunicationProtocol de la
proprit Pilote de TSQLConnection.
Ceci implique galement que la proprit de Port doit tre modifie, puisque le
port 211 tait utilis pour TCP/IP. Assurez-vous de spcifier pour le Port la mme
valeur que celle choisie pour le composant TDSHTTPService dans le Conteneur
serveur.
Aprs avoir procd ces changements et rexcut le Client DataSnap, vous
verrez probablement safficher le message derreur suivant :

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Pour y remdier, il suffit dajouter lunit DSHTTPLayer la clause d'utilisations


(de ClientForm par exemple) du Client DataSnap.

2.2.1.2. AUTHENTIFICATION HTTP


Lutilisation du protocole de communication HTTP prsente notamment
lavantage de pouvoir inclure lAuthentification HTTP. Cette fonctionnalit est
supporte au niveau du Serveur DataSnap par le composant
TDSHTTPServiceAuthenticationManager, comme il est expliqu au point
2.1.1.1.5.
Ds que le gestionnaire dvnements OnHTTPAuthenticate est implment et
quune vrification dauthentification HTTP y est effectue, vous devez vrifier si
les bonnes informations sont transmises, pour obtenir laccs de
TDSHTTPServiceAuthenticationManager. Dans le cas contraire, un message
daccs non-autoris HTTP/1.1 401 saffichera :

Pour transmettre le nom dutilisateur et le mot de passe dauthentification HTTP


du Client au Serveur DataSnap, et plus prcisment au composant
TDSHTTPServiceAuthentication, il est ncessaire de renseigner les proprits
DSAuthUser et DSAuthPassword du composant TSQLConnection (sur le
formulaire client).

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Notez que vous devez galement indiquer une valeur pour le nom dhte
(HostName), sauf si vous ralisez des tests avec un Serveur DataSnap sur la
mme machine locale.

2.3. DPLOIEMENT SERVEUR DATASNAP


Lexemple fonctionne bien lorsque le serveur et le client sont tous deux excuts
sur la mme machine locale ; or, en pratique, le Serveur DataSnap sera excut
sur une machine serveur, avec un ou plusieurs clients connects cette machine
en rseau. Le plus souvent, la machine sur laquelle est dploye lapplication
serveur DataSnap ne dispose pas d'une installation Delphi. Ceci implique quil
vous faudra peut-tre envisager de compiler le serveur DataSnap sans disposer
de solutions dexcution actives, et que vous obtiendrez un seul gros module
excutable.
Puisquaucun composant daccs aux donnes na t utilis, aucun pilote de
bases de donnes supplmentaire ni DLL externe n'est ncessaire ce stade.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

2.3.1. DPLOIEMENT CLIENT DATASNAP


Dans lhypothse o lapplication client DataSnap est excute sur une autre
machine que lapplication serveur, vous devrez vous assurer que le client peut se
connecter au serveur. Pour cela, le composant TSQLConnection du formulaire
client devra spcifier non seulement les valeurs des sous-proprits
CommunicationProtocol et Port de la proprit Driver, mais galement celle de
HostName. vitez daffecter une adresse IP et utilisez plutt un nom DNS
logique, si possible. Il est possible, par exemple, dutiliser la valeur HostName
www.bobswart.nl (il nest pas ncessaire de spcifier le prfixe http:// puisque le
protocole effectivement utilis sera spcifi dans le protocole de communication).

3. DATASNAP ET BASES DE DONNES


OU VOUS VOULEZ
En plus du dveloppement de mthodes serveur simples avec le framework
Delphi 2010 DataSnap, il est possible dajouter au serveur laccs la base de
donnes, en transformant larchitecture en application de base de donnes
multiniveau dans laquelle le serveur DataSnap se connectera la base de
donnes et les clients DataSnap seront lgers ou transparents, sans
ncessiter de pilote de base de donnes (du ct client).
Dans le dploiement DataSnap ralis jusqu prsent, nous nous sommes
contents dutiliser directement le composant SQLConnection et les classes client
gnres, mais il est galement possible dutiliser les deux nouveaux composants
DataSnap TsqlServerMethod et TDSProviderConnection.
Assurez-vous, pour commencer, que le serveur fournit effectivement un
ensemble TDataSet ; pour cela, retournez ServerMethodsUnitDemo et placez
un composant TSQLConnection sur le module de donnes.
Connectez le composant TSQLConnection votre SGBD et votre table favoris
(dans lexemple, la table Employees de la base de donnes BlackfishSQL
exemple).
Pour cela, placez un composant TSQLConnection sur la zone du concepteur
ServerMethods1 (dans lunit ServerMethodsUnitDemo.pas). Paramtrez la
proprit Driver du composant TSQLConnection sur BlackfishSQL. Ouvrez ensuite
la proprit Driver et paramtrez la proprit Database sur le chemin vers
employee.jds dans C:\Documents and Settings\All Users\Documents\RAD
Studio\7.0\Demos\database\databases\BlackfishSQL sous Windows XP ou dans
C:\Users\Public\Documents\ RAD
Studio\7.0\Demos\database\databases\BlackfishSQL sous Windows Vista ou
Windows 7.
Assurez-vous que la proprit LoginPrompt du composant TSQLConnection est
paramtre sur False et ensuite tentez de paramtrer la proprit Connected sur
True pour vrifier si vous pouvez ouvrir la connexion la base de donnes
Employee.jds.
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Placez ensuite un composant TSQLDataSet ct de TSQLConnection et


connectez sa proprit SQLConnection au composant TSQLConnection.

Laissez ensuite le jeu CommandType sur ctQuery et faites cliquez sur la proprit
ellipse pour que la proprit CommandText entre une requte SQL.
SELECT EMP_NO, FIRST_NAME, LAST_NAME, HIRE_DATE, JOB_COUNTRY FROM EMPLOYEE

Assurez-vous que les proprits LoginPrompt et Connected du composant


TSQLConnection sont sur False ainsi que la proprit Active de TSQLDataSet.
Nous devons maintenant ajouter une fonction publique la classe
TServerMethods1 de lunit ServerMethodsUnitDemo pour retourner les contenus
du composant TSQLDataSet.
type
TServerMethods1 = class(TDSServerModule)
SQLConnection1: TSQLConnection;
SQLDataSet1: TSQLDataSet;
private
{ Private declarations }
public
{ Public declarations }
function EchoString(Value: string): string;
function ServerTime: TDateTime;
function GetEmployees: TDataSet;
end;

Comme vous pouvez le voir dans la dfinition TServerMethod1 la nouvelle


fonction est dnomme GetEmployees et limplmentation se prsente comme
suit :
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

function TServerMethods1.GetEmployees: TDataSet;


begin
SQLDataSet1.Open; // make sure data can be retrieved
Result: = SQLDataSet1
end;

Recompilez le serveur et assurez-vous quil fonctionne encore. Remarquez que si


vous avez ferm le serveur DataSnap mais ne pouvez pas le recompiler, il est
probable que le projet serveur DataSnap est toujours en cours dexcution.

3.1. TSQLSERVERMETHOD

Retournez lapplication client DataSnap. Le composant TSQLConnection ne doit


alors plus tre connect au serveur DataSnap (dans le cas contraire, il peut sagir
de la raison pour laquelle vous ntes pas parvenu recompiler le serveur
DataSnap dans la mesure o le processus est toujours en cours d'utilisation).
Nous pouvons paramtrer nouveau Connected sur True pour rafrachir
linformation depuis le serveur et ensuite rgnrer les classes client (avec le
bouton droit).
Pour rcrire lunit ServerMethodsClient prcdente, il est recommand de
supprimer la version prcdente du projet et de slectionner nouveau
Gnrer les classes client DataSnap . Si nous sauvegardons la nouvelle unit
gnre dans le fichier ServerMethodsClient.pas, nous naurons pas modifier le
code client prcdent. Aprs avoir excut nouveau la tche Gnrer les
classes client DataSnap , la classe TServerMethods1Client gnre a t
tendue avec la mthode GetEmployees (listant galement les fonctions
ServerTime et EchoString qui sont toujours disponibles) :
type
TServerMethods1Client = class
private
FDBXConnection: TDBXConnection;
FInstanceOwner: Boolean;
FEchoStringCommand: TDBXCommand;
FServerTimeCommand: TDBXCommand;
FGetEmployeesCommand: TDBXCommand;
public
constructor Create(ADBXConnection: TDBXConnection); overload;
constructor Create(ADBXConnection: TDBXConnection;
AInstanceOwner: Boolean); overload;
destructor Destroy; override;
function EchoString(Value: string): string;
function ServerTime: TDateTime;
function GetEmployees: TDataSet;
end;

Pour utiliser la mthode GetEmployees pour rcuprer le jeu TDataSet, nous


pouvons utiliser un composant TsqlServerMethod de la catgorie dbExpress dans
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

la Palette doutils. Placez TsqlServerMethod sur le formulaire client, connectez sa


proprit SQLConnection sur SQLConnection1 puis ouvrez la liste droulante
ServerMethodName pour afficher toutes les mthodes disponibles que nous
pouvons appeler : un certain nombre de mthodes DSAdmin (qui peuvent tre
affiches en paramtrant la proprit HideDSAdmin du composant TDSServer sur
True), suivies par 3 mthodes DSMetadata, 7 mthodes TServerMethods.AS_xxx
(interface IAppServer originale) et finalement nos mthodes TServerMethods1
EchoString, ServerTime et GetEmployees.
Dans lexemple actuel, nous devons slectionner TServerMethods1.GetEmployees
comme valeur de la proprit ServerMethodName. Le rsultat de
SqlServerMethod est alors un jeu de donnes contenant les enregistrements
employs (ou au moins avec le rsultat de notre dclaration SQL).
Nous pouvons utiliser maintenant la chane habituelle TDataSetProvider,
TClientDataSet et TDataSource pour afficher les donnes dans une grille
TDBGrid.
Placez TDataSetProvider dans le formulaire client et connectez sa proprit
DataSet sur le composant SqlServerMethod. Placez ensuite un composant
TClientDataSet dans le formulaire client et connectez sa proprit ProviderName
sur le composant DataSetProvider. Laissez la proprit RemoteServer en blanc
utilis uniquement dans l'ancienne approche DataSnap mais pas dans la nouvelle
architecture DataSnap.
Finallement, placez TDataSource dans le formulaire client et connectez sa
proprit DataSet au composant TClientDataSet. Nous pouvons ensuite utiliser
TDBGrid et TDBNavigator pour connecter leur proprit DataSource au
composant TDataSource pour afficher les donnes dans le formulaire client.
Pour vrifier la connexion en phase de conception, nous pouvons paramtrer la
proprit Active de ClientDataSet sur True. Ceci fait basculer la proprit Active
de SqlServerMethod (seulement pour un instant pour rcuprer les donnes,
aprs quoi la proprit Active revient sur False), ce qui dfinit la proprit
Connected du composant TSQLConnection sur True afin de permettre la
connexion entre client et serveur DataSnap.
La connexion demeure active moyennant quoi, la fois TClientDataSet et
TSQLConnection, sont actifs et affichent les donnes dans TDBGrid :

Ceci fournit un moyen simple dafficher les donnes en mode lecture seule (dans
la mesure o TSQLServerMethod nautorise pas la combinaison
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

TDataSetProvider-TClientDataSet envoyer des mises jour du client au serveur


DataSnap).
TSQLServerMethod est une solution lgre et pratique pour se connecter des
donnes en lecture seule.
Par consquent, si vous souhaitez fournir des donnes dun serveur DataSnap
des personnes ne devant en aucun cas pouvoir les modifier, larchitecture
actuelle, exposant les rsultats TSQLDataSet de la classe TServerMethods1, est
une bonne ide.
Cependant, si des mises jour sont ncessaires nous devons utiliser une autre
approche pour exposer les donnes.

3.2. TDSPROVIDERCONNECTION
Si nous devons appliquer des mises jour, nous avons besoin dun composant
TDSProviderConnection qui nous donne une rfrence un DataSetProvider du
ct serveur permettant non seulement de lire les donnes mais aussi d'envoyer
les mises jour.
Nous devons tout dabord effectuer un changement sur le module de donnes du
serveur. Cependant, nous navons pour linstant fait quajouter une fonction pour
retourner TDataSet et nous devons ajouter maintenant un vritable
TDataSetProvider et nous assurer quil est export du serveur vers les clients
DataSnap. Par consquent, retournons lunit ServerMethodsUnitDemo et
plaons un composant TDataSetProvider ct de TSQLDataSet, pointant vers la
proprit DataSet de TDataSetProvider vers TSQLDataSet. Nous devons
galement renommer TDataSetProvider pour le rendre intelligible
(dspEmployees).

Recompilons et excutons nouveau le serveur DataSnap pour modifier le client


et appliquer des changements aux donnes exposes.

3.2.1. CLIENT TDSPROVIDERCONNECTION


Pour modifier le client DataSnap afin dutiliser le composant expos
TDataSetProvider, nous devons supprimer les composants TSQLServerMethod et

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

TDataSetProvider du formulaire client et ajouter la place un composant


TDSProviderConnection.
Pointez la proprit SQLConnection de TDSProviderConnection sur le composant
TSQLConnection se connectant au serveur DataSnap. Nous devons galement
entrer une valeur pour la proprit ServerClassName de TDSProviderConnection.
Malheureusement, nous ne disposons pas encore dune liste droulante ce
niveau. Nous devons maintenant entrer manuellement le nom de
TDSServerModule (dans notre cas : TServerMethods1).
Dans lexemple prcdent, TClientDataSet ne connecte que son ProviderName
DataSetProvider1. Cependant, en utilisant le composant TDSProviderConnection,
nous devons tout dabord affecter la proprit RemoteServer de TClientDataSet
au composant TDSProviderConnection puis slectionner une nouvelle valeur pour
la proprit ProviderName (qui tait toujours affecte la valeur
DataSetProvider1, et doit dsormais pointer vers dspEmployees le nom plus
explicite du composant TDataSetProvider expos par le serveur DataSnap).
La liste droulante de la proprit ProviderName doit dsormais proposer loption
dspEmployees (nom du composant TDataSetProvider export de lunit
ServerDataMod).
Nous pouvons maintenant dfinir nouveau la proprit Active du composant
TClientDataSet sur True pour afficher les donnes relles en conception :

Cette opration a galement pour effet de paramtrer la proprit Connected du


composant TSQLConnection sur True. Remarquons, quil ne serait pas bon de
laisser ces deux proprits sur True dans le formulaire client en conception.
Avant tout, si vous ouvrez le projet Client DataSnap dans Delphi, il tentera de se
connecter au serveur DataSnap ce qui provoquera une erreur si le serveur nest
pas dmarr. Ensuite, si vous dmarrez lapplication en excution et quaucune
connexion nest disponible, lapplication gnrera galement une exception. Ceci
vous empche dutiliser lapplication avec des donnes locales ; elle est donc
inoprante en labsence de connexion.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Le meilleur moyen consiste donc inclure une option de menu ou un bouton de


connexion explicite au composant TSQLConnection et/ou activer
TClientDataSet. Cest galement le bon moment pour inclure les informations
nom utilisateur/mot de passe (nous y reviendrons). Pour linstant, assurez-vous
que la proprit Active de TClientDataSet est sur False ainsi que la proprit
Connected du composant TSQLConnection. Ensuite, placez un bouton sur le
formulaire client et ouvrez explicitement TClientDataSet dans le gestionnaire
dvnements OnClick.
procedure TForm2.Button2Click(Sender: TObject);
begin
ClientDataSet1.Open;
end;

Il est maintenant temps dajouter du code pour vritablement changer les


donnes (ct client) et de retourner les modifications au serveur.

3.2.2 MISES A JOUR DE LA BASE DE DONNES


Il existe deux mthodes pour retourner au serveur les modifications ralises sur
le client : automatique ou manuel. Les deux font appel la fin la mme
mthode mais linvocation est soit automatique, soit commande par lutilisateur
(chacune ayant des avantages et des inconvnients).
Dans lapproche automatique, nous pouvons utiliser les vnements
OnAfterInsert, OnAfterPost et OnAfterDelete de TClientDataSet, puisquil sagit
des mthodes ayant apport des changements aux donnes. Dans les
gestionnaires dvnements qui peuvent tre partags par la mme
implmentation nous pouvons appeler la mthode ApplyUpdates de
TClientDataSet pour envoyer les changements (ou Delta ) au serveur pour
retour la base de donnes.
procedure TForm2.ClientDataSet1AfterPost(DataSet: TDataSet);
begin
ClientDataSet1.ApplyUpdates(0);
end;

Si une erreur se produit (enregistrement non trouv) lors de la mise jour, nous
pouvons obtenir un retour dans lvnement OnReconcileError de TClientDataSet
(voir les dtails la section 3.2.3).
Lenvoi manuel des mises jour au serveur DataSnap utilise galement la
mthode ApplyUpdates de TClientDataSet mais ne doit cette fois pas tre
appele par les gestionnaires dvnement OnAfterInsert, OnAfterPost et
OnAfterDelete. Au lieu de cela, nous devons ajouter un bouton au formulaire
client pour permettre lutilisateur de retourner explicitement les modifications
au serveur.
procedure TForm2.btnUpdateClick(Sender: TObject);
ClientDataSet1.ApplyUpdates(0);
end;
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Lavantage de lappel automatique ApplyUpdates est naturellement que


lutilisateur ne pourra pas oublier de retourner les changements au serveur.
Cependant, le dsavantage reste quil est impossible dannuler : lorsquelles sont
postes, les donnes sont appliques au serveur. Dun autre ct, en cas
dapproche manuelle, tous les changements sont conservs ct client dans la
mmoire du composant TClientDataSet. Ceci permet lutilisateur dannuler
certains changements (le dernier, un enregistrement spcifique ou lensemble
des mises jour en attente). Cliquer sur le bouton de mise jour pour appeler
explicitement les mthodes ApplyUpdates lorsque l'utilisateur est prt prsente
un risque doubli, nous devons par consquent ajouter une vrification au
formulaire ou lapplication pour lempcher de se fermer sil reste des
modifications dans TClientDataSet. Ce dernier peut tre vrifi ultrieurement en
recherchant dans la proprit ChangeCount de TClientDataSet.

3.2.3. RECONCILIATION DES ERREURS


La mthode ApplyUpdates du composant TClientDataSet a un argument : le
nombre maximum derreurs autorises avant larrt de lapplication dautres
mises jour. Si deux clients se connectent au serveur DataSnap, obtiennent les
donnes Employees et ralisent tous deux des changements sur le premier
enregistrement, daprs ce que nous avons construit jusque-l, les deux clients
pourraient retourner lenregistrement mis jour au serveur DataSnap en
utilisant la mthode ApplyUpdates de leur composant TClientDataSet. Si les deux
passent la valeur zro comme argument MaxErrors dApplyUpdates alors le
second qui tentera d'effectuer la mise jour sera stopp. Le deuxime client
pourrait passer une valeur numrique suprieure zro pour indiquer quun
nombre fixe derreurs/conflits est autoris avant larrt de la mise jour.
Cependant, mme si le second client passe -1 comme argument (pour indiquer
que la mise jour doit se poursuivre quel que soit le nombre derreurs), les
enregistrements modifis par le prcdent client ne seront pas mis jour. En
dautres termes, des actions de rconciliations doivent tre effectues pour grer
les mises jour des enregistrements et champs dj modifis.
Heureusement, Delphi propose une fonction utile conue spcifiquement pour ce
cas. Chaque fois quil est ncessaire de rconcilier des erreurs, il est prfrable
de lajouter lapplication Client DataSnap (ou den crire une).
Pour utiliser celle de Delphi, slectionnez Fichier | Nouveau - Autre, allez dans la
sous-catgorie Fichiers Delphi de Projets Delphi dans le dialogue Nouveaux
lments et slectionnez licne Dialogue Erreur et conciliation.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Cliquez ensuite sur OK, pour ajouter RecError.pas votre projet DataSnapClient.
Cette unit contient la dfinition et limplmentation du dialogue Erreur de mise
jour utilisable pour rsoudre les erreurs de mise jour de la base de donnes.

Une instance de ReconcileErrorForm est cre dynamiquement, la vole


lorsque cela est ncessaire. La question qui se pose alors est de savoir quand
lutiliser ou ne pas lutiliser. La rponse est en fait simple, pour chaque
enregistrement dont la mise jour a chou (quelle quen soit la raison), le
gestionnaire dvnement OnReconcileError du composant TClientDataSet est
appel ; il est dfini comme suit :
procedure TForm2.ClientDataSet1ReconcileError(DataSet: TClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind;
var Action: TReconcileAction);

Ce gestionnaire dispose de quatre arguments : le composant TClientDataSet


ayant produit lerreur ; un ReconcileError spcifique contenant un message sur la
cause de la condition derreur ; le type UpdateKind (insrer, effacer ou modifier)
ayant gnr lerreur et enfin lAction qui doit tre ralise.
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Le paramtre Action peut retourner les valeurs suivantes (dans lordre des
valeurs enum relles) :
- raSkip Ne pas mettre jour lenregistrement mais conserver les
modifications non ralises dans le log de changement. Prt pour un
nouvel essai la prochaine fois.
- raAbort Annulation de lensemble de la rconciliation ; aucun autre
enregistrement ne sera pass au gestionnaire dvnements
OnReconcileError.
- raMerge Fusion de lenregistrement mis jour avec lenregistrement
actuel de la base de donnes (distante), modification uniquement des
valeurs de champ (distants) si elles ont chang de votre ct.
- raCorrect Remplacement de lenregistrement mis jour par une valeur
corrige de lenregistrement du gestionnaire dvnement (ou dans
ReconcileErrorDialog). Avec cette option lintervention utilisateur est
requise (saisie).
- raCancel Annulation de tous les changements l'intrieur de
l'enregistrement et retour lenregistrement (local) original.
- raRefresh Annulation de tous les changements lintrieur de
lenregistrement avec rechargement des valeurs de la base de donnes
(distante) actuelle (et non depuis lenregistrement local original).
Lintrt de ReconcileErrorForm est de saffranchir de ces considrations. Il suffit
dinclure lunit ErrorDialog dans la dfinition de formulaire principal du client
DataSnap, de cliquer sur le formulaire Client DataSnap et de choisir Fichier |
Utiliser lunit pour obtenir le dialogue Utiliser lunit. Avec le formulaire client
comme unit courante, le dialogue Utiliser lunit liste la seule unit disponible :
ErrorDialog.
Il suffit de la slectionner et de cliquer sur OK.
La seconde opration raliser est dcrire une ligne de code dans le
gestionnaire dvnements OnReconcileError pour appeler la fonction
HandleReconcileError de lunit ErrorDialog (qui vient dtre ajoute la liste
dimportation ClientMainForm). La fonction HandleReconcileError dispose des
mmes quatre arguments que OnReconcileError (ce qui nest naturellement pas
une concidence). Il sagit donc de passer les arguments de lun lautre rien
de plus, rien de moins. Le gestionnaire OnReconcileError du composant
TClientDataSet peut tre cod comme suit :
procedure TFrmClient.ClientDataSet1ReconcileError(DataSet: TClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind;
var Action: TReconcileAction);
begin
Action := HandleReconcileError(DataSet, UpdateKind, E)
end;

3.2.4. DEMONSTRATION DE LA RECONCILIATION DES ERREURS


Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

La question est dsormais de savoir comment cela fonctionne en pratique. Pour


le tester, vous devez naturellement disposer de deux (ou plus) clients DataSnap
fonctionnant simultanment. Pour un test complet utilisant le client DataSnap
actuel et les applications serveur DataSnap, vous devez passer par les tapes
suivantes :
- Dmarrez lapplication serveur DataSnap.
- Dmarrez le premier client DataSnap et cliquez sur le bouton Connect.
- Dmarrez le second client DataSnap et cliquez sur le bouton Connect. Les
donnes seront obtenues du mme Serveur DataSnap qui fonctionne dj.
- Utilisez le premier client DataSnap pour modifier le champ "FirstName" du
premier enregistrement.
- Utilisez le second client DataSnap pour modifier galement le champ
"FirstName" du premier enregistrement.
- Cliquez sur le bouton "Valider modifications" du premier Client DataSnap.
Toutes les mises jour seront appliques sans problme.
- Cliquez sur le bouton "Valider modifications" du second Client DataSnap.
Cette fois une ou plusieurs erreurs se produisent car la valeur du champ
"FirstName" du premier enregistrement a t modifie (par le premier
client DataSnap) ; pour cela et ventuellement pour dautres
enregistrements en conflit le gestionnaire dvnements OnReconcileError
est appel.
- Dans le dialogue Erreur de mise jour, vous pouvez dsormais
exprimenter les Actions de rconciliation (passer, annuler, fusionner,
corriger, annuler et rafrachir) pour mieux comprendre leurs effets. Notez
en particulier les diffrences entre Passer et Annuler et entre Corriger,
Rafrachir et Fusionner.
Passer amne lenregistrement suivant en sautant la mise jour requise (pour
le moment). Le changement non-appliqu demeure dans le log de changement.
Annuler saute galement la mise jour requise mais annule toutes les mises
jour ultrieures (du mme lot de mises jour). La requte de mise jour en
cours est saute dans les deux cas mais avec Passer les autres requtes de mise
jour se poursuivent alors qu'Annuler annule lensemble de la requte
ApplyUpdates.
Rafrachir oublie toutes les mises jour effectues l'enregistrement et le
rafrachit avec la valeur actuelle de la base de donnes du serveur. Fusionner
tente de fusionner lenregistrement mis jour avec celui du serveur et place vos
changements lintrieur de lenregistrement serveur. Rafrachir et Fusionner ne
poursuivent pas la requte de changement, les enregistrements sont
synchroniss aprs Rafrachir et Fusionner (la requte de changement peut tre
r-excute aprs Passer ou Annuler).
Corriger, loption la plus puissante, permet de personnaliser la mise jour dans
le gestionnaire dvnements. Pour cela, il est ncessaire dcrire du code ou de
saisir les valeurs vous-mme.

3.3. DPLOIEMENT BASE DE DONNES DATASNAP


Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Le dploiement d'un serveur DataSnap utilisant des bases de donnes peut tre
plus complexe que le dploiement du serveur DataSnap avec lequel nous avons
dbut. Pour lapplication client, rien ne change il sagit toujours dun client
lger/intelligent qui peut tre dploy comme un excutable autonome en
ajoutant lunit MidasLib aux clauses dutilisation.
Pour le serveur DataSnap, nous devons maintenant aussi dployer les pilotes de
base de donnes. Les pilotes et fichiers dpendent de la base de donnes
slectionne. En utilisant DBX4, pensez vrifier le composant TSQLConnection
et les fichiers dbxconnections.ini et dbxdrivers.ini dans C:\Documents and
Settings\All Users\ Documents\RAD Studio\dbExpress\7.0 (Windows XP) ou dans
C:\Users\Public\Documents\RADStudio\dbExpress\7.0 (Windows Vista et
Windows 7).
Le fichier dbxdrivers.ini indique pour le pilote donn les composants
DriverPackageLoader et MetaDataPackageLoader (pointant gnralement vers le
mme package). Pour BlackfishSQL, cela signifie que DBXClientDriver140.bpl doit
tre dploy ainsi que Blackfish. Pour plus dinformations sur le dploiement de
BlackfishSQL, reportez-vous fichier deploy_en.htm dans le rpertoire
RADStudio\7.0.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

3.4. REUTILISATION DES MODULES DE DONNEES DISTANTS EXISTANTS


S'il existe des classes TRemoteDataModule, vous pouvez toujours les utiliser
conjointement avec le nouveau DataSnap. Mais vous devez supprimer quelques
fonctionnalits du serveur (spcialement les lments COM).
En premier lieu, si vous souhaitez migrer une application Serveur DataSnap
existante et pas seulement le module de donnes distant, vous devez dsinscrire
le serveur DataSnap en lanant lexcutable en ligne de commande avec loption
de ligne de commande /unregister. Si vous ne faites pas cela depuis le dbut,
vous ne serez pas en mesure de dsinscrire le module de donnes distant du
registre (sauf si vous restaurez ultrieurement une sauvegarde du projet).
Dans lunit pour le module de donnes distant, nous devons supprimer le code
de la section dinitialisation. Pour conserver une unit compatible entre Delphi
2007 (ou antrieur) et 2009 (ou postrieur), vous pouvez placer ce code dans
{$IFDEF} comme suit :
{$IF CompilerVersion >= 20}
initialization
TComponentFactory.Create(ComServer, TRemoteDataModule2010,
Class_RemoteDataModule2010, ciMultiInstance, tmApartment);
{$IFEND}
end.

Nous devons galement supprimer la routine UpdateRegistry du projet ou la


placer galement dans {$IFDEF}.
{$IF CompilerVersion >= 20}
class procedure UpdateRegistry(Register: Boolean;
const ClassID, ProgID: string); override;
{$IFEND}

Le changement le plus important pour raliser lopration consiste supprimer la


bibliothque de type (ou fichiers .ridl) et lunit dimportation de bibliothque de
type. Ils ne peuvent pas demeurer dans {IFDEF}s, par consquent, si vous
devez conserver une version Delphi 2007 ou antrieure (COM) et Delphi 2009 ou
ultrieure (sans COM) du serveur DataSnap vous devrez faire maintenant une
copie du projet. Nous devons utiliser un composant TDSServerClass de
lapplication serveur DataSnap et retourner la classe TRemoteDataModule,
comme nous avons fait prcdemment.
Finalement, nous devons nous assurer que toutes les mthodes personnalises
qui ont t ajoutes TRemoteDataModule sont dplaces de la section protge
(DataSnap COM par dfaut) la section publique (linformation mthode est
gnre dans larchitecture DataSnap sans COM).

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

4. FILTRES DATASNAP
LES DONNES COMME VOUS VOULEZ
Dans cette section, nous aborderons le fonctionnement des filtres et la faon
dutiliser les filtres existants (tels que la compression) ou de construire de
nouveaux filtres DataSnap. Les filtres DataSnap sont des DLL spcifiques qui
interceptent le flux doctets de communication et peuvent fonctionner dans une
chane de filtres complte.
Nous pouvons par exemple combiner compression et cryptage, journalisation et
compression, etc.
Nous devons indiquer quel(s) filtre(s) doivent tre utiliss par le serveur et le
client DataSnap deux endroits. Pour le serveur, nous devons indiquer une liste
dans la proprit Filters du composant TDSTCPServerTransport et pour les
clients, nous devons indiquer une liste similaire de filtres dans les clauses
dutilisation du projet client DataSnap. Cela suffit pour le client dans la mesure
o chaque filtre DataSnap doit automatiquement senregistrer pour utilisation.
Lors du gestionnaire dvnements OnConnect, nous pouvons examiner les filtres
enregistrs utiliss pour la connexion (par exemple en utilisant une fonction
spcifique LogInfo pour crire ces informations dans un fichier journal) :
procedure TServerContainer1.DSServer1Connect(
DSConnectEventObject: TDSConnectEventObject);
var
i: Integer;
begin
LogInfo('Connect ' + DSConnectEventObject.ChannelInfo.Info);
for i:=0 to DSConnectEventObject.Transport.Filters.Count-1 do
LogInfo(' Filter: ' +
DSConnectEventObject.Transport.Filters.GetFilter(i).Id);
end;

4.1. FILTRE ZLIBCOMPRESSION

Examinons par exemple un filtre DataSnap existant, livr avec Delphi 2010 qui
peut tre utilis pour comprimer les flux de donnes entre le serveur DataSnap
et lunit DbxCompressionFilter.
Le composant TDSTCPServerTransport (pour TCP/IP) et le composant
DSHTTPService (pour HTTP) ont une proprit Filters contenant
TTransportFiltersCollection. Nous pouvons cliquer sur lellipse de la proprit
Filters pour modifier la collection de filtres. Dans ce dialogue, nous pouvons
ajouter un nouvel lment TTransportFilterItem et utiliser linspecteur dobjets
pour paramtrer FilterId et quelques proprits optionnelles. Delphi 2010 est
livr avec le filtre ZLibCompression qui peut tre spcifi ici comme FilterId.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Remarquons quen plus de la proprit Filters du composant


TDSTCPServerTransport ct serveur, nous devons galement spcifier que nous
souhaitons galement utiliser ce filtre ct client (pour compresser les requtes
sortantes et dcompresser les rponses entrantes). Pour cela, nous devons
seulement ajouter lunit DbxCompressionFilter la clause dutilisation de
ClientForm. Ceci enregistrera automatiquement TTransportCompressionFilter
pour sassurer quil sera utilis pour communiquer avec le serveur.
Si vous n'ajoutez pas l'unit DbxCompressionFilter la clause dutilisation,
lexcution du client gnrera une exception avec le message suivant :

4.2. FILTRE DE JOURNALISATION (LOG)


Delphi 2010 DataSnap est ouvert pour nous permettre de dfinir nos propres filtres de
transport. Nous pouvons raliser cette opration en drivant une nouvelle classe du type
TTransportFilter. Dans cette nouvelle classe, nous pouvons viter les mthodes de base et
les implmenter. Nous pouvons par exemple crer une classe TLogFilter comme suit :

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

unit LogFilter;
interface
uses
SysUtils, DBXPlatform, DBXTransport;
type
TLogFilter = class(TTransportFilter)
private
protected
function GetParameters: TDBXStringArray; override;
function GetUserParameters: TDBXStringArray; override;
public
function GetParameterValue(const ParamName: UnicodeString): UnicodeString; override;
function SetParameterValue(const ParamName: UnicodeString;
const ParamValue: UnicodeString): Boolean; override;
constructor Create; override;
destructor Destroy; override;
function ProcessInput(const Data: TBytes): TBytes; override;
function ProcessOutput(const Data: TBytes): TBytes; override;
function Id: UnicodeString; override;
end;
const
LogFilterName = 'Log';

Limplmentation de cette classe peut demeurer vierge pour lessentiel. Dans la


mesure o le seul objectif du filtre est de journaliser les donnes mises lors des
mthodes ProcessInput et ProcessOutput, nous pouvons laisser la plupart des
autres mthodes vides. Limplmentation de mthodes non-vides seffectue
comme suit :

function TLogFilter.SetParameterValue(const ParamName, ParamValue: UnicodeString): Boolea


begin
Result := True;
end;
constructor TLogFilter.Create;
begin
inherited Create;
end;
destructor TLogFilter.Destroy;
begin
inherited Destroy;
end;
function TLogFilter.ProcessInput(const Data: TBytes): TBytes;
begin
Result := Data; // journalisation donnes entrantes
end;
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

function TLogFilter.ProcessOutput(const Data: TBytes): TBytes;


begin
Result := Data; // journalisation donnes sortantes
end;
function TLogFilter.Id: UnicodeString;
begin
Result := LogFilterName;
end;

Finalement, une partie importante de limplmentation du filtre de transport


DataSnap est la partie enregistrement de la section dinitialisation et de
finalisation. Ceci permet de sassurer que le client DataSnap pourra trouver
le filtre de transport et lutiliser quand cela est ncessaire.
initialization
TTransportFilterFactory.RegisterFilter(LogFilterName, TLogFilter);
finalization
TTransportFilterFactory.UnregisterFilter(LogFilterName);
end.

Comme nous lavons vu, pour utiliser le filtre transport dans le serveur
DataSnap, nous devons lajouter la liste des filtres de TDSTCPServerTransport
ou du composant TDSHTTPService.
En phase de conception, le filtre ZLibCompression est dj connu mais pas les
nouveaux filtres (sauf si nous les ajoutons un package pour les installer).
Heureusement, nous pouvons galement ajouter les filtres de transport en
excution en ajoutant lunit filtre la clause dutilisation de
ServerContainerUnitDemo puis en ajoutant le filtre manuellement (par nom) la
liste des filtres, par exemple dans :
procedure TServerContainer1.DataModuleCreate(Sender: TObject);
begin
DSTCPServerTransport1.Filters.AddFilter(LogFilterName);
DSHTTPService1.Filters.AddFilter(LogFilterName);
DSHTTPService1.Active := True;
end;

Ceci permet de sassurer que le serveur utilise LogFilter et que le client lutilisera
automatiquement aprs lajout de lunit LogFilter la clause dutilisation du
client. Sinon, le message derreur suivant saffichera :

Remarquons que chaque application serveur et clients DataSnap obtient son


propre fichier de log et bien que le mme filtre de journalisation soit utilis, nous
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

navons pas ajouter dinformation telle que ParamStr(0) pour identifier quelle
cible produit effectivement le message de log.

4.3. FILTRE DE CRYPTAGE


Aprs lexemple simple de la section 4.2, il est clair que le dveloppement de
filtres personnaliss plus complexes nest pas rellement compliqu. En fait, il
existe dj certains filtres tiers (voir notamment
http://www.danieleteti.it/?p=168 contenant 9 filtres additionnels pour DataSnap
2010 classs en trois groupes : Hash prenant en charge MD5, MD4, SHA1 et
SHA512 ; Cipher prenant en charge Blowfish, Rijndael, 3TDES et 3DES et
Compress prenant en charge LZO. Lensemble du code source est disponible.

5. CIBLES WEB DATASNAP


COMME VOUS VOULEZ (SUITE)

Au-del des cibles Windows, un assistant permet de produire des cibles ISAPI,
CGI ou Excutable dbogueur dapplication Web. Nous aborderons dabord les
avantages de ces cibles et dmontrerons comment produire un groupe de projet
unique avec trois cibles diffrentes partageant les mmes units personnalises ;
il en rsulte un seul groupe de projets avec trois projets produisant une cible
diffrente pour le mme objet serveur DataSnap.
Bien que les applications serveur DataSnap que nous avons conues fonctionnent
correctement, certains moments il est impossible de dployer ces applications
serveur. Par exemple, lorsquil est impossible ou interdit douvrir les ports requis
du pare-feu pour permettre aux clients de se connecter au serveur. Cependant,
dans la plupart des cas, un site Web est hberg sur un serveur Web et le port
80 est gnralement ouvert (pour le serveur Web).
Si nous supposons que Microsoft Internet Information Services (IIS) est utilis
comme serveur Web, nous pouvons utiliser le nouvel assistant Application
DataSnap WebBroker pour produire un projet qui sera dploy sur IIS.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Cet assistant propose trois choix dont lun nest pas vritablement une
application WebBroker mais essentiellement un client de dbogage dapplication
Web nutiliser qu cette fin. Ce client est trs puissant puisquil permet
dutiliser le Dbogueur dapplication Web (dans le menu Outils de lEDI Delphi)
comme application hte tout en dboguant lapplication Client DataSnap avec le
dbogueur dapplication Web.
Le dbogage des applications CGI ou ISAPI/NSAPI est plus dlicat. Par
consquent le Dbogueur dapplication Web est un choix pertinent pour les
applications encore en dveloppement.
Les cibles restantes (DLL ISAPI/NSAPI/Excutable autonome CGI) peuvent tre
slectionnes pour de vritables projets serveur DataSnap.

Remarquons que le choix de Excutable autonome CGI nest pas une excellente
ide car cet excutable sera charg/dcharg chaque requte entrante. En
ajoutant le temps de connexion une base de donnes pour effectuer quelques
oprations, on comprend bien les problmes de performance qui peuvent se
poser. Lutilisation dune cible ISAPI rsultera dans une DLL qui nest charge
quune fois et demeure en mmoire afin que les requtes suivantes (dautres
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

utilisateurs) ne souffrent pas dune pnalit de performance additionnelle.


Linconvnient majeur dune DLL ISAPI est quil nest pas simple de remplacer (si
vous navez quun accs FTP au serveur Web) mais il existe suffisamment de
gestionnaires ISAPI pour solutionner ce problme votre place (pour plus de
dtails contactez votre fournisseur dhbergement Web).
Lautre inconvnient dune cible ISAPI DLL rside dans les difficults de
dbogage, exigeant de charger IIS comme application hte ce qui ne
fonctionne pas toujours comme prvu. Cependant, ce problme particulier est
rsolu par la prsence dun excutable Dbogueur dapplication Web il suffit de
sassurer dutiliser deux projets utilisant les mmes code et mthodes
personnalises DataSnap. Il sagit dun bon point de dpart pour une premire
dmonstration, ajoutant des techniques relles pour obtenir un squelette
oprationnel.

5.1. DBOGUEUR DAPPLICATION WEB


Utilisons tout dabord lAssistant Nouvelle application WebBroker DataSnap pour
crer une nouvelle application Excutable dbogueur dapplication Web.
Indiquons par exemple DSWAD pour le nom de classe et cochons loption
Supporter lauthentification HTTP.

Aprs avoir cliqu sur OK, un nouveau projet est cr avec trois units. En
labsence de fichiers Project1 et Unit1 dans le rpertoire de projets par dfaut, le
projet sera dnomm Project1 et les units Unit1, ServerMethodsUnit1 et Unit2.
La premire unit doit tre un formulaire vide unique pour lExcutable
dbogueur dapplication Web et non requis pour les autres cibles Web.
Enregistrez cette unit dans WADForm.pas. La deuxime unit est dnomme
ServerMethodsUnit1.pas et contient notre module serveur driv de
TDSServerModule comme indiqu dans la bote de dialogue. Nous reviendrons
cette unit dans un moment ; nous pouvons lenregistrer pour linstant sous le
nom ServerMethodsUnit1.pas. La troisime unit dnomme Unit2 est un module
Web trois composants dj prsents (trois, si vous navez pas coch loption
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Supporter lauthentification HTTP). Cette unit doit recevoir les requtes


entrantes et les distribuer aux modules du serveur DataSnap du projet.
Enregistrez cette unit dans DSWebMod.pas.
Enfin, enregistrez le projet sous DSWADServer.dproj pour indiquer quil sagit du
serveur DataSnap Dbogueur dapplication Web.

5.2. CIBLE ISAPI


Avant de poursuivre la modification et la personnalisation des units
ServerMethodsUnit1.pas et DSWebMod.pas, nous devons tout dabord ajouter un
nouveau projet au groupe cette fois une application DLL ISAPI/NSAPI. Cliquez
avec le bouton droit sur ProjectGroup et slectionnez Ajouter un nouveau projet
pour obtenir le rfrentiel objet et dmarrer un nouveau projet. Dans la
catgorie Serveur DataSnap, utilisez nouveau lassistant Nouvelle application
WebBroker DataSnap pour crer une nouvelle application DLL ISAPI/NSAPI.
Cette fois, vous navez modifier aucune option dans la partie infrieure de la
bote de dialogue puisque nous allons rutiliser les units existantes du projet
DSWADServer.

Cliquez sur OK pour gnrer un nouveau projet (qui sera ajout au groupe),
nomm Project1, avec les units ServerMethodUnit2.pas et Unit1.pas ajoutes
au nouveau projet.
Maintenant, au lieu dutiliser les nouvelles units ServerMethodUnit2.pas et
Unit1.pas, nous devons utiliser ServerMethodUnit1.pas et DSWebMod.pas qui
font dj parti du projet DSWADServer. Cliquez avec le bouton droit sur le nud
ServerMethodUnit2.pas sous le nud Project1.dll et slectionnez Retirer du
Projet. Cliquez sur OK dans la bote de dialogue de confirmation (remarquez que
si vous ne les avez pas encore sauvegardes, il nest naturellement pas utile de
supprimer les fichiers ServerMethodUnit2.pas et .dfm du disque). Faites de
mme avec Unit1.pas, afin que Project1.dll ne contienne plus dunits. Ensuite,
cliquez avec le bouton droit sur Project1.dll et ajoutez les units DSWebMod.pas
et ServerMethodUnit1.pas au projet. Finalement, renommez Project1 en
DSISAPIServer.dproj pour complter le groupe de projet.
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Vous devriez avoir maintenant un groupe avec deux projets partageant les units
DSWebMod et DSSererMethodUnit1.pas comme prsent dans la copie dcran
suivante :

Cette configuration permet de construire deux projets utilisant DSWADServer


comme cible pour les tests et le dbogage et DSISAPIServer pour le dploiement
effectif du serveur DataSnap sur IIS.
Avant de poursuivre en ajoutant des mthodes Web ServerMethodsUnit1, nous
devons tout dabord corriger le projet ISAPI/NSAPI en supprimant du fichier le
code crant une instance automatique de TDSServerModule. En effet
TDSServerModule tant un module de donnes, nous obtiendrons un message
derreur si nous tentons dexcuter la DLL ISAPI car il ne peut exister quun
module Web dans lapplication.
Ouvrez le code source du projet DSISAPIServer.dpr et modifiez le bloc principal
comme suit :
begin
CoInitFlags := COINIT_MULTITHREADED;
Application.Initialize;
Application.CreateForm(TWebModule2, WebModule2);
// Application.CreateForm(TServerMethods1, ServerMethods1);
Application.Run;
end.

Ceci permettra dviter le message derreur indiquant qu'un seul module de


donnes est autoris. Remarquons que vous pouvez ne pas voir ce message
derreur lors de lappel du composant ISAPI DLL (dploy) mais une erreur
serveur ou de temporisation cest pourquoi il est important de se souvenir de
ce problme.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

5.3. METHODES SERVEUR, DEPLOIEMENT ET CLIENTS


Lors de lajout de fonctionnalits, nous devons travailler uniquement sur lunit
ServerMethodUnit1.pas qui est partage par les deux cibles. Par dfaut, une
mthode exemple est dj incluse mais comme pour les versions Windows du
serveur DataSnap, nous pouvons ajouter deux autres mthodes (voir la section
2.1.4 pour les composants et le code source ncessaires dans l'unit Mthodes
serveur).
Lorsque les mthodes serveur sont implmentes, nous pouvons dployer ISAPI
DLL sur un serveur Web comme Microsoft IIS. Ceci est expliqu en dtail dans un
article de Jim Tierney sur
http://blogs.embarcadero.com/jimtierney/2009/08/20/31502 nous ny
reviendrons donc pas ici.
Si vous ne disposez pas de serveur Web de dploiement, vous pouvez manipuler
le serveur DataSnap ISAPI dploy sur mon serveur. Remarquons que
TDataSetProvider nest pas expos et que les donnes ne sont pas retournes
dans la mthode GetEmployees mais que les mthodes ServerTime et EchoString
fonctionnent parfaitement ce qui doit suffire pour crire un client DataSnap de
test sur ce serveur.
Avant de connecter le serveur ISAPI DataSnap lintrieur dune application
client, il est pertinent dutiliser lExplorateur de donns pour valider la connexion
au serveur ISAPI DataSnap. Lexplorateur de donns dispose dune nouvelle
catgorie dnomme DATASNAP, si vous louvrez, une premire connexion
dnomme DATASNAPCONNECTION est disponible que vous pouvez modifier (en
cliquant avec le bouton droit et en slectionnant Modifier la connexion).
Dans cette bote de dialogue, nous pouvons indiquer le protocole, l'hte (vous
pouvez utiliser www.bobswart.nl si vous navez pas votre propre serveur Web),
le port et le chemin URL vers lapplication serveur ISAPI DataSnap (cgibin/DSISAPIServer.dll). Cliquez sur Tester la connexion pour vous assurer que
tout fonctionne.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Cliquez maintenant sur OK pour refermer la bote de dialogue. Dans lexplorateur


de donnes, vous pouvez dsormais dvelopper le nud
DATASNAPCONNECTION pour afficher les tables, vues, procdures, fonctions et
synonymes. Vous constaterez que les procdures incluent tous les DSAdmin,
DSMetaData, TServerMethods1.AS_xxx ainsi que nos trois mthodes serveur
personnalises : EchoString, ServerTime et GetEmployees.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Sans quil soit ncessaire dcrire une application client DataSnap, nous pouvons
dsormais tester certaines mthodes. Par exemple EchoString (pour sassurer du
retour de ce que nous envoyons).
Si nous cliquons avec le bouton droit sur la procdure
TServerMethods1.EchoString, nous pouvons choisir Afficher les paramtres pour
afficher une nouvelle fentre dans lEDI o nous pourrons saisir la valeur du
paramtre de Value (par exemple 42). Ensuite, en cliquant avec le bouton droit
sur cette nouvelle fentre, nous pouvons slectionner Excuter pour excuter la
mthode serveur distante. Le rsultat est affich ci-dessous :

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Ceci dmontre que nous pouvons appeler les mthodes serveur personnalises
depuis le serveur DataSnap. Pour connecter lapplication client DataSnap au
serveur, il suffit de modifier les proprits de TSQLConnection. Prcdemment,
nous nous sommes connects la version Windows du serveur DataSnap ; nous
devons maintenant modifier ces paramtres pour se connecter la version Web.

Rappelez vous que si vous dsirez rellement utiliser DSISAPIServer.dll de mon


serveur Web que jai dsactiv TDataSetProvider et ne retourne aucune valeur
dans les mthodes GetEmployees mais vous pouvez appeler les mthodes
ServerTime et EchoString.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

6. REST

ET

JSON...

COMME VOUS VOULEZ


DataSnap 2010 prend en charge REST et JSON. DataSnap 2010 prend en charge
REST pour les requtes DataSnap HTTP. Par exemple, si lURL du serveur
DataSnap est http://www.bobswart.nl/cgi-bin/DSISAPIServer.dll, nous pouvons
y ajouter /datasnap/rest, suivi du nom de la classe Server Method, de la
mthode et des arguments.
La syntaxe gnrique se prsente comme suit :
http://server/datasnap/rest/<class>/<method>/<parameters>

Pour la mthode ServerTime du module TServerMethod1 de DSISAPIServer.dll sur mon


serveur, lURL se prsente comme suit :
http://www.bobswart.nl/cgi-bin/DSISAPIServer.dll/datasnap/rest/TServerMethods1/ServerTime

Lappel de cette URL REST produit un rsultat JSON, par exemple dans le navigateur :

Le rsultat affich dans le navigateur est un construit JSON :


{"result":["2009-10-16 16:01:33.145"]}

Marco Cant fournit dautres dtails sur REST dans son livre blanc consacr
Delphi 2010 et aux clients REST.

6.1. RAPPELS (CALLBACKS)


En plus dtre le rsultat dappels REST aux serveurs DataSnap, JSON est
galement utilis lors de limplmentation de mthodes de rappel. DataSnap
2010 prend en charge les fonctions de rappel ct client, excutes dans le
contexte dune mthode serveur. Cela signifie que lors de lexcution dune
mthode serveur (appele par le client DataSnap), le serveur peut appeler une
fonction de rappel passe en tant quargument par le client la mthode
serveur.
Par exemple, modifions la mthode EchoString afin de lui ajouter une fonction de
rappel.
La dfinition de la mthode EchoString doit tre modifie comme suit :
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

function EchoString(Value: string; callback: TDBXcallback): string;

Le type de TDBXcallback est dfini dans l'unit DBXJSON. Avant de pouvoir


implmenter la nouvelle mthode EchoString, nous devons tout dabord
examiner comment la mthode de rappel peut tre dfinie ct client (aprs
tout, il sagit dune mthode client pouvant tre appele par le serveur).
Ct client, nous devons dclarer une nouvelle classe, drive de TDBXCallback
et viter la mthode Execute.
type
TCallbackClient = class(TDBXCallback)
public
function Execute(const Arg: TJSONValue): TJSONValue; override;
end;

Dans la mthode Execute, nous obtenons largument Arg de type TJSONValue,


que nous pouvons cloner pour manipuler le vritable contenu. La mthode
Execute peut galement retourner lui-mme TJSONValue.
function TCallbackClient.Execute(const Arg: TJSONValue): TJSONValue;
var
Data: TJSONValue;
begin
Data := TJSONValue(Arg.Clone);
ShowMessage('Callback: ' + TJSONObject(Data).Get(0).JSonValue.value);
Result := Data
end;

Dans cet exemple, la mthode de rappel indique la valeur passe la mthode EchoString,
avant que la mthode neffectue un vritable retour (cest--dire pendant quelle est encore
en cours dexcution). Limplmentation de la nouvelle mthode EchoString ct serveur doit
dsormais disposer la valeur de chane dans un objet TJSONObject et la passer la
mthode callback.Execute comme suit :
function TServerMethods2.EchoString(Value: string; callback: TDBXcallback): string;
var
msg: TJSONObject;
pair: TJSONPair;
begin
Result := Value;
msg := TJSONObject.Create;
pair := TJSONPair.Create('ECHO', Value);
pair.Owned := True;
msg.AddPair(pair);
callback.Execute(msg);
end;

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Remarquons que la fonction de rappel est excute (ct client) et retourne


avant que la mthode EchoString nait termin ct serveur.
Enfin, lappel la mthode EchoString ct client doit galement tre modifi
puisque nous devons maintenant passer une classe de rappel une instance du
nouveau TCallbackClient comme second argument.
var
MyCallback: TCallbackClient;
begin
MyCallback := TCallbackClient.Create;
try
Server.EchoString(Edit1.text, MyCallback);
finally
MyCallback.Free;
end;
end;

Ce simple exemple dmontre comment utiliser des mthodes de rappel ct


client dans DataSnap 2010.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

7. DATASNAP ET .NET OU VOUS


VOULEZ (SUITE)
Delphi Prism 2010 est utilis pour construire un client DataSnap .NET pour les
serveurs Win32 conus jusqu prsent. Pour construire le client Delphi Prism
2010 DataSnap, assurez-vous qu'un serveur DataSnap est oprationnel pour que
nous puissions nous y connecter ds la phase de conception.
Dmarrez Delphi Prism 2010, et choisissez View | Server Explorer pour afficher
lexplorateur serveur Delphi Prism. Nous devons tout dabord raliser une
connexion pour vrifier que nous pouvons vraiment travailler avec le serveur
DataSnap.
Lexplorateur serveur affiche une arborescence avec un nud racine dnomm
Data Connections. Cliquez avec le bouton droit sur Data Connections et
slectionnez Add Connection. Dans la bote de dialogue qui suit, slectionnez
DataSnap dans la liste des sources de donnes (remarquez que vous devez
cliquer sur Change si une source de donnes est dj prslectionne).

Vous pouvez dcocher la bote Always use this selection sauf bien sr si vous
ne voulez construire que des connexions de donnes DataSnap.
Cliquez sur Continue pour obtenir la page suivante du dialogue. Vous pouvez
alors indiquer les dtails de connexion au serveur DataSnap. Dans la liste de
choix Protocol, nous pouvons choisir tcp/ip ou http. Ensuite, vous devez indiquer
lhte (cest--dire le nom de la machine sur laquelle le serveur DataSnap est
excut ventuellement localhost si vous effectuez les tests sur la mme
machine locale). Ensuite, vous devez indiquer le numro de port. Par dfaut, il
sagira du port 80 pour HTTP et du port 211 pour TCP/IP, mais vous savez
maintenant que les deux valeurs peuvent (ou doivent) tre diffrentes assurezvous au moins dindiquer la mme valeur ici que celle indique dans le/les
composants de transport de lunit ServerContainerUnitDemo.
La proprit suivante contient le chemin daccs. Il nest important que si vous
devez vous connecter un serveur DataSnap bas sur Web Broker (o vous
devez indiquer le chemin URL pour accder au serveur Web DataSnap c'est-dire, la partie aprs the http://..../ domaine.
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Finalement, noubliez pas dindiquer le nom dutilisateur et le mot de passe


dauthentification si le serveur DataSnap utilise lauthentification HTTP.

Cliquez sur le bouton de test de connexion pour vrifier que la connexion peut
tre ralise vers le serveur DataSnap indiqu. Ceci vous permettra dafficher le
message Test connection succeeded si tout a t indiqu correctement.
Lorsque vous cliquez sur OK, une nouvelle entre pour la connexion DataSnap
sera ajoute larbre des connexions aux donnes (dans ce cas pour un nud
localhost). Si vous devez dvelopper le nouveau nud, vous trouverez des sousnuds pour Tables, Views et Stored Procedures ; les deux premiers sont vides
mais Stored Procedures doit contenir toutes les mthodes serveur exposes du
serveur DataSnap y compris nos mthodes personnalises EchoString,
GetEmployees et ServerTime.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Nous pouvons maintenant tester certaines mthodes serveur depuis


lexplorateur. Par exemple, en cliquant avec le bouton droit sur la mthode
EchoString et en slectionnant View Parameters. Cette opration affiche une
nouvelle fentre o nous pouvons entrer une valeur pour le paramtre Value.
Saisissons 42 ; cliquons avec le bouton droit dans la fentre et slectionnons
Execute. Cette opration excute la mthode EchoString du serveur DataSnap et
indique les rsultats juste dessous la fentre des paramtres de procdure
enregistre :

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Il serait plus intressant de savoir comment nous pouvons rcuprer et utiliser


les donnes de la table Employees en utilisant la mthode GetEmployees. Cette
procdure stocke na pas de paramtres mais nous pouvons slectionner la
commande View Parameters qui retourne une liste vide de paramtres de
procdure stocke. Cliquons nouveau avec le bouton droit sur cette fentre et
slectionnons Execute. Cette fois, le rsultat est le jeu complet denregistrements
de la table Employee comme retourn par la mthode GetEmployees :

7.1. CLIENT WINFORMS


Lutilisation des mthodes serveur DataSnap dans lexplorateur est intressante
mais il est plus utile de les appeler depuis une application .NET. Pour ce dernier
exemple choisissez Fichier | Nouveau projet pour dmarrer lassistant nouveau
projet de Delphi Prism. Ceci donne un aperu des cibles disponibles.
Dans le type de projet, slectionnez Windows Application et modifiez le nom
WindowsApplication1 en DataSnapClient.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Si vous cliquez sur OK, un nouveau projet DataSnapClient sera cr dans lEDI
Delphi Prism avec une unit Main.pas pour le formulaire principal.
Dans Server Explorer, slectionnez la nouvelle connexion vers le serveur
DataSnap que nous avons cre la section prcdente. Lexplorateur de
proprits affiche les proprits et notamment ConnectionString qui doit se
prsenter comme suit :
communicationprotocol=http;hostname=localhost;port=8080;dsauthenticationuser=Bob;ds
authenticationpassword=Swart

Cliquez avec le bouton droit sur le nud de connexion aux donnes et


slectionnez Generate Client Proxy.
Cela gnre un fichier ClientProxy1.pas avec la dfinition dune classe dnomme
TServerMethods1Client et un certain nombre de mthodes (EchoString,
ServerTime et GetEmployees). Le snippet de dfinition de classe se prsente
comme suit :
TServerMethods1Client = class
public
constructor (ADBXConnection: TAdoDbxConnection);
constructor (ADBXConnection: TAdoDbxConnection; AInstanceOwner: Boolean);
function EchoString(Value: string): string;
function ServerTime: DateTime;
function GetEmployees: System.Data.IDataReader;

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

part la classe proxy, plusieurs rfrences ont t ajoutes au nud References


du projet : Borland.Data.AdoDbxClient et Borland.Data.DbxClientDriver.
Comme nous le voyons dans le snippet de TServerMethods1Client, cette classe a
deux constructeurs : les deux avec un paramtre ADBXConnection et la
deuxime avec un paramtre boolen AInstanceOwner. Cela signifie que nous
devons appeler le constructeur avec un argument. Pour cela nous devons
modifier les paramtres du projet. Cliquez avec le bouton droit sur le nud
DataSnapClient dans lexplorateur de solution et slectionnez Proprits. Dans la
fentre, choisissez longlet Compatibilit et cochez loption Allow Create
constructor calls permettant dappeler le constructeur Create passant les
arguments au lieu dutiliser le nouvel oprateur.

Nous pouvons maintenant retourner au formulaire principal et lui ajouter un


bouton. Dans lvnement Clic du bouton, nous pouvons crer une connexion
au serveur DataSnap et appeler une de ses mthodes.
method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
var
Client: ClientProxy1.TServerMethods1Client;
Connection: Borland.Data.TAdoDbxDatasnapConnection;
begin
Connection := new Borland.Data.TAdoDbxDatasnapConnection();
Connection.ConnectionString :=

'communicationprotocol=http;hostname=localhost;port=8080;dsauthenticationuser=Bob;dsa
enticationpassword=Swart';
Connection.Open;
try
Client := ClientProxy1.TServerMethods1Client.Create(Connection);
MessageBox.Show(
Client.EchoString('Delphi Prism 2010'));
finally
Connection.Close;
end;
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

end;

Le rsultat est lcho de Delphi Prism 2010 comme indiqu ci-dessous.

De la mme faon, nous pouvons appeler la mthode GetEmployees et affecter


les rsultats la vue DataGridView. Ceci pose un problme dans la mesure o
GetEmployees retourne IDataReader (lquivalent dun rsultat de TSQLDataSet)
et pas un jeu DataSet ni une table DataTable. Nous devons donc crire quelques
lignes de code pour charger les rsultats de GetEmployees dans une nouvelle
table DataTable dans un jeu DataSet (lquivalent de TClientDataSet du ct
Win32).
method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
var
Client: ClientProxy1.TServerMethods1Client;
Connection: Borland.Data.TAdoDbxDatasnapConnection;
Employees: System.Data.IDataReader;
ds: System.Data.DataSet;
dt: System.Data.DataTable;
begin
Connection := new Borland.Data.TAdoDbxDatasnapConnection();
Connection.ConnectionString :=

'communicationprotocol=http;hostname=localhost;port=8080;dsauthenticationuser=Bob;dsa
enticationpassword=Swart';
Connection.Open;
try
Client := ClientProxy1.TServerMethods1Client.Create(Connection);
Employees := Client.GetEmployees;
ds := new DataSet();
dt := new DataTable("DataSnap");
ds.Tables.Add(dt);
ds.Load(Employees, LoadOPtion.PreserveChanges, ds.Tables[0]);
dataGridView1.DataSource := ds.Tables[0];
MessageBox.Show(
Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Client.EchoString('Delphi Prism 2010'));


finally
Connection.Close;
end;
end;

Le rsultat est les donnes suivantes prsentes dans une vue en grille d'une
application Delphi Prism WinForms dmontrant que nous pouvons crire des
clients .NET lgers pour se connecter aux serveurs DataSnap.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

8. SYNTHSE
Nous avons dmontr dans ce livre blanc que nous pouvons utiliser DataSnap o
nous voulons (sous Windows avec une interface, un service ou une application
console ou sur le Web avec une application CGI, ISAPI ou Dbogueur
dapplication Web) ainsi que comme clients Win32 ou .NET et comme nous
voulons en utilisant TCP/IP, HTTP avec authentification HTTP et sur option avec
des filtres de compression, de cryptage, etc.
DataSnap 2010 offre des extensions et amliorations substantielles par rapport
DataSnap 2009 et des volutions remarquables depuis les versions originales de
DataSnap et MIDAS bases sur COM.
Bob Swart Bob Swart Training & Consultancy (eBob4)^
Embarcadero Technologies, Inc. est un diteur leader de solutions primes pour
les dveloppeurs dapplications et les professionnels des bases de donnes pour
les aider concevoir et excuter plus efficacement et rapidement leurs solutions
quels que soient les langages de programmation ou les plates-formes. 90 des
100 premires socits mondiales du classement Fortune et une communaut
active de plus de 3 millions dutilisateurs dans le monde font confiance aux outils
dEmbarcadero pour maximiser leur productivit, rduire les cots, simplifier la
gestion du changement et de la conformit et acclrer linnovation.
Les produits phares dEmbarcadero sont notamment : Embarcadero Change
Manager, RAD Studio, DBArtisan, Delphi, ER/Studio, JBuilder et Rapid
SQL. La socit Embarcadero a t cre en 1993 et son sige se situe San
Francisco ; lentreprise est prsente dans le monde entier et son site Web peut
tre consult ladresse www.embarcadero.com.

Copyright 2009 Bob Swart (aka Dr.Bob - www.drbob42.com). Tous droits rservs.

Vous aimerez peut-être aussi