Exemple Datasnap

Résolu
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 25 juil. 2012 à 10:37
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 27 juil. 2012 à 17:40
Bonjour,

Je suis sur un dev client-serveur Firebird avec Delphi XE2, en utilisant Datasnap. Je rencontre des difficultés pour passer un objet (tstrings par exemple) du serveur au client.
Pour expliquer un peu mieux, sur le serveur, j'ai une methode getList qui fait un select d'un champ sur une table et retourne au client les valeurs dans un tstrings.
J'ai essayé de plusieurs façons :

1 - TStrings en retour
function getList : TStrings;
- Creation du Result (TStringList.Create)
- Creation dynamique IBSQL (select) et remplissage Result

-> Fonctionne quand j'appelle la methode à partir du client (ListBox.Items.AddStrings(Server.getList)), mais fuite mémoire sur le serveur dans la mesure où le "Result" de la fonction getList n'est pas libéré sur le serveur. De plus, à la fermeture du client, j'ai un runtime error 204 si je fais un seul appel à la fonction, runtime error 216 si j'en fais plus d'un...

2 - TStrings en paramètres par valeur ou par variable
Procedure getList(slRetour : TStrings); ou Procedure getList(var slRetour : TStrings);
- Creation dynamique IBSQL (select) et remplissage slRetour

Appel client :
MyList : TStrings;

MyList := TStringList.Create;
Server.getList(MyList);
ListBox.Items.AddStrings(MyList);
MyList.free;

Sur le passage par valeur, ça ne fonctionne pas et j'ai "operation de pointeur incorrecte"
Sur le passage par variable, qui me semble la façon la plus propre (mais est-ce qu'on peut faire un passage par variable d'un client à un serveur...), ça fonctionne la première fois, mais j'ai "operation de pointeur incorrecte" à la fermeture de l'appli (runtime error 204), au second appel, j'ai un message "Interne : le type tkPointer n'est actuellement pas supporté"

C'est dommage parce que le Datasnap, ça a l'air vraiment bien pensé... Je ne sais pas si je ne programme pas comme il faut ou si le problème vient d'XE2. J'ai trouvé ça sur le net (https://forums.embarcadero.com/thread.jspa?messageID=426045), j'ai modifié le fichier en question, recompilé mon client et mon serveur, mais ça n'a rien changé.

Avez-vous déjà rencontré ce problème ? (et surtout comment l'avez-vous solutionné ?)

Merci d'avance pour vos réponses



Simon

11 réponses

informatixo Messages postés 129 Date d'inscription mercredi 4 février 2004 Statut Membre Dernière intervention 25 juillet 2012 1
25 juil. 2012 à 18:46
Bonsoir à tous,

J'arrive un peu tard visiblement mais bon ça peut être utile je pense vu qu'il s'agit du même cas de figure (XE2 / datasnap / Firebird 2.5).

Pour passer un objet du serveur au client, il nous a été conseillé par embarcadero de le serialiser/deserialiser à l'aide de JSON quand cela concerne des objets ou des types de données spécifique. En utilisant une unité commune entre le client et le serveur quand il s'agit de type de données personnalisés afin que JSON sache comment le sérialiser/désérialiser. Il y a un tutoriel sur le net la dessus si mes souvenirs sont bons !

Voilà j'espère avoir pu faire avancer le schmilblik !

Que la force soit avec vous !
3
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
27 juil. 2012 à 17:40
Alors, on avance...
Pour le problème "erreur distante : erreur DBX : le pilote n'a pas été correctement initialisé. La bibliothèque est manquante, n'est pas correctement installée, sa version est incorrecte, ou le pilote n'est pas dans le chemin système" : J'ai réinstallé FireBird 2.5, et recopié le fbClient.dll dans le dossier sysWOW64. J'y ai aussi mis le dbxfb.dll ainsi que les fichiers midas.* trouvés dans le dossier embarcadero. Et là, merveille, j'affiche le dataset dans le client !!!

Reste le souci de fuite memoire pour les fonctions qui retournent un objet...

Simon
3
ThierryLaborde Messages postés 91 Date d'inscription mercredi 12 septembre 2007 Statut Membre Dernière intervention 23 janvier 2017 1
26 juil. 2012 à 13:20
Bonjour,

Si le but c'est d'envoyer une liste de chaine de caractères pourquoi ne pas utiliser un TJsonArray.

Côté serveur :

function TServerMethods1.ListeString: TJSONArray;
var
  JsonArray:TJSONArray;
  Liste:TStringList;
  i: Integer;
begin
  Liste:= TStringList.Create;

  // Remplissage de la liste....

  JsonArray:=TJSONArray.Create;
  for i := 0 to Liste.Count-1 do
  begin
    JsonArray.Add(Liste[i]);
  end;
  Result:=JsonArray;
end;


Et côté client (Dans l'exemple je met le résultat dans une listbox) :

procedure TForm1.Button1Click(Sender: TObject);
var
  ServerDs:TServerMethods1Client;
  JsonArray:TjsonArray;
  i:integer;
begin
  ServerDs: =TServerMethods1Client.Create(SqlConnection1.DBXConnection);
  JsonArray:=ServerDs.ListeString;
  for i := 0 to JsonArray.Size-1 do
  begin
    ListBox1.Items.Add(JsonArray.Get(i).Value);
  end;
end;



Voila en espérant que ça aide.

Thierry Laborde

ArrowEcs
Responsable Technique Embarcadero

http://blogs.embarcadero.com/tlaborde
2
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
25 juil. 2012 à 11:13
Bonjour,

FireBird 2 + datasnap + XE2 compatibles ?
Sur Embarcadero, on cite Interbase et pas Firebird...

cantador
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
25 juil. 2012 à 11:22
Bonjour Cantador,

Pas de problème avec Firebird (et même 2.5 ). J'ai des methodes du serveur qui retournent des strings et qui marchent sans aucun problème... Visiblement c'est dès que je veux faire passer des objets (ici des strings) que ça bloque...

Simon
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
25 juil. 2012 à 15:07
essaie une dll..

cantador
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
25 juil. 2012 à 15:15
Je vais utiliser le composant datasetprovider, qui permet d'accéder à distance à un dataset, mais je pensais que pour optimiser, ça aurait été plus rapide de passer un tstrings qu'un dataset... tant pis. Merci quand même pour tes interventions Cantador et à la prochaine.

Simon
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
25 juil. 2012 à 16:42
pas content car ton problème n'est pas résolu
interroge néanmoins embarcadero..

cantador
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
25 juil. 2012 à 16:50
Bé moi non plus... ça m'aurait bien arrangé de passer un tstrings, mais bon. Je vais essayer de poser la question. Ceci dit, il y a un tuto chez eux qui reprend le code que je voulais utiliser (celui avec la fuite mémoire...)
Du coup, je m'intéresse aux datasetprovider. Pas évident...

Simon
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
27 juil. 2012 à 11:17
Bonjour et merci pour vos réponses.

à tlaborde :
Je veux bien essayer avec un JSONArray. Mais à priori, la liste créée côté serveur n'est pas libérée ("Liste:=TStringList.Create;
), ni le jsonarray (dans la mesure où il peut être libéré, je ne sais pas, mais dans le code serveur, il y a bien un "JsonArray:=TJSONArray.Create;"). Dans ce cas, on aura encore une fuite mémoire sur le serveur et autant retourner directement la liste en résultat de la fonction (fuite mémoire pour fuite mémoire, autant coder plus simplement )

Par ailleurs, je rencontre également des difficultés avec le groupe de composants SQLConnection + DSProviderConnection + ClientDataset.
Sur le serveur (machine : windows server 2008 r2), j'ai un SQLConnection, un DatasetProvider (exported = true) et un SQLDataset. Sur le client (machine : Xp pro sp3), je peux connecter le SQLConnection, le dsProviderConnection, mais dès que je veux connecter le ClientDataset, j'ai un message "erreur distante : erreur DBX : le pilote n'a pas été correctement initialisé. La bibliothèque est manquante, n'est pas correctement installée, sa version est incorrecte, ou le pilote n'est pas dans le chemin système".
"Distante", je suppose que ça signifie que l'erreur vient du serveur. Sur le serveur, j'ai copié dans system32 (vu que le serveur est une appli win32) le fichier "C:\Program Files\Embarcadero\RAD Studio\9.0\Redist\win32\dbxfb.dll" en provenance de mon poste de dev (config actuelle). J'ai essayé toutes les combinaisons (fichier "C:\Program Files\Embarcadero\RAD Studio\9.0\Redist\win64\dbxfb.dll" et repertoire serveur "sysWOW64"), rien n'y fait. J'ai également essayé avec Firebird 2.5 (64 bits et 32 b), firebird 2.1 (32 b) et firebird 2.0, sans succès... Avez-vous déjà rencontré le problème ? Y a t'il une manipulation à faire avec cette dll dbxfb.dll ?


Simon
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
27 juil. 2012 à 11:27
ah oui, j'ai oublié ! Un autre souci : si je fais un serveur avec authentification (id et password), l'assistant de création du module client datasnap me bloque sur l'authentification car il prend l'ID pour le mot de passe. Si je veux utiliser l'assistant, je suis obligé de "désécuriser" mon serveur le temps de la création du client datasnap...


Simon
0
Rejoignez-nous