Accueil | MEET | PFEG | IGC | STG | BTS IG | BTS SIO | Cours | Didactique | Exos | Glossaire | Labo | Sujets | Outils Imprimer cette page



Rechercher
    
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Cas Alarme - Concepts

A/ Principes de fonctionnement

1. Application distribuée

Nous allons écrire une application très simple qui permettra d'illustrer le concept d'application distribuée. L'application permet à l'utilisateur de saisir un entier, le mémorise, est capable de le restituer... pas grand chose en fait !

Son originalité tient au fait que le travail de l'application sera partagé entre deux programmes :

  • gereVal.exe : acquisition de la valeur et restitution de cette valeur à l'utilisateur.
  • memoVal.exe : mémorisation de la valeur (et affichage "témoin" de cette mémorisation).

Le programme gereVal est client de memoVal en ce sens qu'il utilise ses capacités de mémorisation d'une valeur. Le schéma ci dessous illustre le fonctionnement de l'ensemble :

Lorsque l'utilisateur souhaite conserver une valeur (la retenue d'une opération en cours par exemple), il la communique au programme gereVal (étape 1). Celui-ci fait alors appel au programme memoVal pour la mémorisation de cette valeur (étape 2).

Lorsque l'utilisateur souhaite retrouver cette valeur, le programme gereVal demande à memoVal de lui restituer la valeur mémorisée (étape 3), puis l'affiche à l'utilisateur (étape 4).

Remarques :

  • L'application est distribuée entre deux programmes distincts.
  • Les deux programmes peuvent s'exécuter sur deux machines différentes du réseau, le traitement peut être réparti entre deux ordinateurs.

2. Quelques notions sur DCOM

La technologie utilisée est assez complexe, mais il suffit en fait d'en comprendre les grands principes pour pouvoir la mettre en ouvre à l'aide d'un outil de développement.

a. Qu'est-ce-qu'un serveur et un client ?

Un serveur DCOM est un programme capable de permettre à d'autres programmes (ses clients) d'utiliser certains de ses objets (au sens poo). Cette possibilité se résume à deux choses essentielles :

  • Le client (ici gereVal) doit pouvoir déclarer un objet qui sera actif au sein du programme serveur (ici memoVal).
  • Le programme client doit pouvoir appeler les méthodes de l'objet créé, ces méthodes s'exécutant en fait au sein du programme serveur (et donc éventuellement sur une autre machine !).

b. Notion d'interface

En programmation objet, on appelle l'interface d'une classe l'ensemble des méthodes (et éventuellement des propriétés) déclarées publiques, donc visible depuis l'extérieur. Chaque classe possède une interface et un ensemble de propriétés et de méthodes privées lui permettant de réaliser effectivement les fonctionnalités de son interface (on parle d'implémentation de la classe).

Avec DCOM, les notions d'interface et d'implémentation ont la même signification, mais ces deux éléments sont réellement distincts. On peut résumer la situation ainsi :

Programmation objet "classique" :

  • Chaque classe possède une interface et une implémentation.
  • Une interface est un ensemble de propriétés et d'entêtes de méthodes.
  • Chaque implémentation réalise les fonctionnalités de l'interface de sa classe.

Technologie DCOM :

  • Une interface DCOM est un type décrit par un ensemble de propriétés et d'entêtes de méthodes.
  • Une classe d'objets DCOM est un type décrit par un ensemble de propriétés et de méthodes. Ce type implémente au moins une interface DCOM.
  • Chaque interface DCOM peut être implémentée par plusieurs classes DCOM.
  • Chaque classe DCOM peut implémenter plusieurs interfaces DCOM.

Intérêts de cette architecture :

  • Une classe DCOM peut réaliser plusieurs interfaces, ce qui signifie concrètement qu'un objet de cette classe peut servir à plusieurs choses distinctes. Par exemple, une même classe pourrait implémenter une interface "liste chaînée de caractères" et une interface "ensemble de caractères". Selon les besoins du client, un objet de cette classe pourrait être utilisé comme une liste ou comme un ensemble.
  • Une interface peut être réalisée par plusieurs classes. Il est donc très facile d'offrir plusieurs manières de réaliser la même chose, certaines pouvant être plus performantes que d'autres. On peut également changer facilement la classe réalisant une interface sur une machine donnée sans pour autant perturber le fonctionnement des clients.

c. Types d'application serveur

Il existe trois types d'applications serveur :

  • "en processus" : l'application serveur s'exécute sur la même machine et dans le même processus que l'application cliente.
  • "hors processus" : l'application serveur s'exécute sur la même machine que l'application cliente, mais dans un processus différent.
  • "distant" : les deux applications s'exécutent sur des machines différentes.

d. Appel de procédure distant

Au niveau de l'application cliente, on ne connaît que l'interface. On déclare donc une variable du type de l'interface, et on obtient ainsi un accès à la création dynamique d'un objet sur le serveur.

Une fois l'objet créé sur le serveur, on peut appeler l'une de ses méthodes, toujours via l'interface. Lorsque le serveur est un serveur distant, le mécanisme mis en ouvre est appelé RPC (Remote Procedure Call).

  • L'appel a lieu au niveau du client.
  • Les informations concernant cet appel (notamment les paramètres) sont transmis au serveur.
  • L'appel est reconstitué sur le serveur comme s'il s'agissait d'un appel local.
  • Les paramètres "sortie" sont retransmis au client une fois la procédure exécutée.

Ce mécanisme s'appelle le "marshaling".

e. Caractéristiques d'une classe DCOM

Type d'instanciation

  • Interne : seule l'application serveur peut créer des objets de la classe et les transmettre aux clients.
  • Instance unique : un seul objet de la classe peut exister au sein de l'application serveur, ce qui signifie que l'application serveur sera exécutée autant de fois qu'il y aura création d'objet par un client.
  • Instance multiple : il peut exister plusieurs objets de la classe au sein de l'application serveur. Celle-ci sera donc exécutée lors de la création du premier objet par un client et se terminera lorsque tous les objets créés auront été détruits.

Modèle de Thread

Puisque plusieurs programmes clients peuvent accéder à l'application serveur, il faut faire attention aux conflits d'accès. Le modèle de Thread détermine ce qui est protégé et sécurisé automatiquement par DCOM.

  • Modèle thread "unique" : tout est protégé automatiquement, c'est-à-dire que DCOM sérialise tous les accès et s'assure qu'il n'y a jamais de conflit.
  • Modèle thread "compartiment" (appartment) : chaque objet de la (ou des) classe(s) de l'application serveur est protégé automatiquement par DCOM. Par contre, les données globales de l'application ne le sont pas, ce qui signifie que la sécurisation de leur accès est à la charge du programmeur.
  • Autres modèles : la sécurisation des données est entièrement à la charge du programmeur.

B/ Présentation algorithmique de l'application

L'application serveur

Principe de l'application "MemoVal"

Notre application serveur doit définir une interface DCOM (interface ImemInt) prévoyant les services utilisables par les clients et une classe DCOM (classe CoMemInt) implémentant ces services.

Cette architecture peut se représenter de la manière suivante :

> IMemInt

L'interface "ImemInt" doit fournir les services suivants :

  • mémoriser une valeur
  • restituer la valeur précédemment mémorisée
  • afficher la valeur mémorisée (cette fonctionnalité nous permettra de contrôler la bonne exécution de l'application serveur).

Il est donc possible de la décrire par :

Interface IMemInt

procédure setValeur(entier val) // permet de mémoriser une valeur entière.

procédure getValeur(variable entier val) // restitue la valeur mémorisée.

procédure showValeur // affiche la valeur mémorisée sur la machine serveur

Fin interface

> CoMemInt

La classe CoMemInt doit implémenter l'interface ImemInt, c'est-à-dire réaliser de manière concrète l'ensemble des services prévus. Il convient donc de choisir une implémentation de ces services. Ici, ce choix est assez simple : nous allons utiliser une donnée privée de type entier pour mémoriser la valeur fournie par l'application cliente.

Voici la description de la classe "CoMemInt" :

Classe CoMemInt (implémente ImemInt)

valeur : entier

procédure setValeur(entier val)

début

valeur ß val

fin

procédure getValeur(variable entier val)

début

val ß valeur

fin

procédure showValeur

début

afficher(valeur)

fin

Fin Classe

Remarques :

  • Il est facile d'écrire une autre classe implémentant l'interface ImemInt (en mémorisant la valeur sur disque par exemple).
  • Notre classe CoMemInt pourrait tout à fait implémenter une autre interface (il suffirait de lui ajouter les méthode ad hoc.
  • La méthode showValeur permettra de tester le bon fonctionnement de notre serveur.

L'application cliente

Principe général

L'application "gèreVal" doit :

  • Déclarer un objet de type ImemInt qui permettra de demander la création par le serveur d'un objet CoMemInt.
  • Utiliser la capacité de mémorisation d'une valeur de cet objet distant.
  • Demander la restitution de la valeur à l'objet distant.
  • Provoquer l'affichage de la valeur mémorisée par l'objet distant.

Interface utilisateur

L'écran ci-dessous résume les possibilités offertes à l'utilisateur :

Réalisation

// déclaration de la variable ImemInt et création de l'objet distant

valeurMemo : IMemInt;

valeurMemo ß CoMemInt.CreateRemote('192.168.210.2')

Remarque : cette méthode est obligatoirement implémentée par toute classe DCOM. Elle permet la création d'un objet distant sur la machine dont l'adresse IP est passée en paramètre.

// Mémorisation d'une valeur

afficher("Valeur à mémoriser : ")

saisir(i)

valeurMemo.setValeur(i);

// Restitution de la valeur

valeurMemo.getValeur(i);

afficher(i)

// Demande d'affichage par l'application serveur

valeurMemo.showValeur;

C/ Réalisation à l'aide de Delphi

1. Création de l'application serveur

Créez deux répertoires : un pour le serveur, un autre pour le client. Lancez Delphi, créez une nouvelle application et enregistrez-la dans le répertoire serveur (ficheMemoVal.pas, memoVal.dpr).

Créez un nouvel objet automation (page ActiveX) :

Remarque : sous Delphi, une classe DCOM est appelée une CoClasse.

La fenêtre d'édition de la bibliothèque de type s'ouvre. Fermez-la et enregistrez l'unité dans le répertoire serveur sous le nom memInt.pas (fichier... enregistrer sous).

2. Définition de l'interface supportée par la CoClasse "CoMemInt"

Choisissez "langage pascal" (et non IDL) dans les options d'environnement (onglet bibliothèque de types). Delphi a généré une interface IMemInt (vide pour le moment) comme interface par défaut pour notre CoClasse CoMemInt. Choisissez l'option "bibliothèque de type" du menu "voir" afin de compléter cette interface.

Ajoutez trois méthodes à l'interface IMemInt :

  • La méthode setValeur qui possède un paramètre entier "val". Il s'agit d'un paramètre d'entrée.
  • La méthode getValeur qui possède un paramètre entier "val" (paramètre de sortie, modificateur var).
  • La méthode showValeur chargée d'afficher la valeur mémorisée (elle servira de "témoin").

3. Définition des méthodes de la CoClasse

L'outil de définition d'interface COM a généré le squelette de la CoClasse et des méthodes destinées à implémenter l'interface ImemInt (fichier memInt.pas).

Il vous suffit de compléter la classe Delphi TMemInt qui correspond à la CoClasse CoMemInt :

  • Ajout d'une propriété entière "valeur" en partie privée.
  • Définition des méthodes de la classe (showValeur se contente d'afficher la valeur à l'écran, les autres ont été vues plus haut).

4. Recensement et configuration du serveur

Pour pouvoir être utilisé, le serveur doit être recensé dans le système. Il suffit pour cela d'exécuter l'application. Vous pouvez ensuite vérifier le recensement de la CoClasse memInt à l'aide du programme "dcomcnfg.exe".

Remarque : il est possible de recenser ou d'annuler le recensement du serveur en utilisant le programme "tregsvr.exe" fourni avec Delphi.

Le programme "dcomcnfg.exe" permet également de configurer les accès au serveur d'objets com :

  • Dans l'onglet Applications, choisir "MemInt objet".
  • Dans l'onglet "sécurité", attribuez les permissions d'accès et les permissions d'exécution à "tout le monde".
  • Dans l'onglet "identité", demandez à utiliser le compte de l'utilisateur interactif (ceci permettra de voir le serveur s'exécuter).

5. Création de l'application cliente

Choisissez "tout fermer" dans le menu fichier et créez une nouvelle application. Enregistrez ce projet dans le répertoire client (ficheGereVal.pas, gereVal.dpr).

6. Intégration du composant serveur

Pour que l'application cliente puisse utiliser le composant serveur, il faut qu'elle soit informée de son existence et qu'elle possède les informations concernant son (ou ses) interface(s).

Il vous suffit pour cela d'ajouter le fichier memoVal_TLB.pas dans la clause uses de la fiche principale "ficheGereVal" (ce fichier a été généré lors de la construction du serveur).

Remarque :

Delphi offre également une autre solution : importer la bibliothèque de types définies à l'étape précédente par l'intermédiaire du menu projet. Cette importation est inutile dans notre cas, mais il est intéressant de connaître cette possibilité. Cette importation peut :

  • Recréer une unité contenant toutes les informations nécessaires à l'exploitation d'une bibliothèque de types.
  • Générer automatiquement un composant Delphi qui encapsule la CoClasse et en simplifie encore l'utilisation (ce mécanisme est appelé le "Wrapper de composant").

7. Utilisation de la CoClasse

L'unité memoval_TLB intégrée au projet, il ne reste plus qu'à utiliser l'interface et la CoClasse pour gérer un objet MemInt.

  • Déclarez une donnée privée dans la classe de la fiche :

    valeurMemo:MemInt;

Il s'agit d'une interface, le type MemInt est équivalent à ImemInt (équivalence déclarée dans MemoVal_TLB.pas)

  • Créez les boutons suivants sur la fiche :
    • créer : création de l'objet serveur sur la machine serveur désignée par son adresse IP.
    • mémoriser : stockage d'une valeur dans l'objet serveur
    • restituer : lecture de la valeur stockée
    • afficher : affichage de la valeur par l'objet serveur

Voici le code associé à chacun de ces boutons :

procedure Tfm_gereVal.bt_creerClick(Sender: TObject);

begin

valeurMemo:=CoMemInt.CreateRemote('192.168.210.2');

end;

  • valeurMemo est une variable de type interface ImemInt. Cette variable devient un accès à l'objet CoMemInt créé par cet appel à CreateRemote.
  • L'adresse IP indiquée est celle de la machine hébergeant l'application serveur memoVal. On pourrait également indiquer le nom de cette machine.
  • Un appel à la méthode Create permettrait la création d'un objet uniquement dans le cas où serveur et client se trouvent sur la même machine.

procedure Tfm_gereVal.bt_memoriserClick(Sender: TObject);

var i:integer;

begin

i:=StrToInt(InputBox('Mémorisation','Valeur entière :',''));

valeurMemo.setValeur(i);

end;

  • Il est nécessaire d'inclure l'unité SysUtils pour la fonction StrToInt.

procedure Tfm_gereVal.bt_restituerClick(Sender: TObject);

var i:integer;

begin

valeurMemo.getValeur(i);

ShowMessage(IntToStr(i));

end;

  • Il est nécessaire d'inclure l'unité Dialogs pour la procédure ShowMessage.

procedure Tfm_gereVal.bt_afficherClick(Sender: TObject);

begin

valeurMemo.showValeur;

end;

  • Quel effet va produire cet appel ?

Voici le formulaire de l'application gereVal :

- Construisez le projet.

D/ Déploiement de l'application

1. Recensement

Chacune des deux applications nécessite un recensement sur la machine d'exécution.

Pour l'application serveur, ce recensement est fait à l'aide de tregsvr.exe ou simplement en lançant le programme memoVal.exe. Le recensement peut être annulé à l'aide de "tregsvr -u memoVal.exe".

Pour l'application cliente, le recensement ne concerne que la bibliothèque de types. Il peut être fait automatiquement sur la machine de développement en cas d'importation de cette bibliothèque, ou manuellement par "tregsvr -t memoVal.tlb" en cas de simple clause "uses" (c'est notre cas), ou encore en cas de déploiement sur une autre machine. Le recensement peut être annulé par "tregsvr -u memoVal.tlb".

Remarque : si l'application serveur doit être déployée sur une autre machine du réseau, son exécution suffira à la recenser. Il faudra par contre modifier l'adresse IP ou le nom de machine mentionné dans l'application cliente.

2. Observation du fonctionnement

  • Installez le programme client sur deux machines différentes.
  • Lancez l'application gereVal sur l'une de ces deux machines, memoVal est automatiquement lancée sur le serveur.
  • Cliquez successivement sur "créer", "mémoriser" et "restituer".
  • Lancez gereVal sur la seconde machine cliente, une seule application memoVal tourne sur le serveur.
  • Cliquez successivement sur "créer", "mémoriser" et "restituer".
  • Cliquez sur le bouton "restituer" de la première machine cliente : il y a bien deux objets MemInt distincts en exécution.
  • Cliquez sur le bouton "afficher" d'une des deux machines clientes : l'exécution est bien localisée sur le serveur.

Vous pouvez également observer le fonctionnement de l'application memoVal à l'aide du debogueur. Pour cela :

  • Lancez Delphi.
  • Chargez le projet memoVal.
  • Positionnez un point d'arrêt (dans la méthode bt_memoriserClick par exemple).
  • Lancez l'application.
  • Lancez l'application gereVal depuis l'explorateur.
  • Cliquez sur "créer", puis "mémoriser" : le programme serveur entre en mode deboguage.

Remarque : avec deux postes, vous pouvez même déboguer les deux applications en même temps.

   

_____________________________________________  
© - Réseau C E R T A 

Ministère de l'éducation nationale, de l'enseignement supérieur et de la recherche