OBJETS DISTRIBUES : Corba
TP3 : Naming service (Propriété+Calculette)
Soit l’interface suivante du fichier IDL « calculator.idl » :
interface Calculator {
attribute long memoire;
long ajouter(in long val);
long soustraire(in long val);
long multiplier(in long val);
long diviser(in long val);
};
Ecrire le serveur qui crée un servant et l'enregistre au naming service.
ETAPE
1 :
Ecrire une première version qui l’implémente sans passer par le name service
ETAPE 2 :
Ecrire ensuite une version qui fait l’enregistrement au nameservice.
Note : l’include pour les définitions du Naming Service est « #include <OB/CosNaming.h> »
Attention : CosNaming.lib est nécessaire en plus dans le projet si vous utilisez Visual C++
Voici un makefile pour Windows (nmake)
Voici un exemple de code permettant de faire accès au Naming service coté serveur (« orb » étant de type « CORBA::ORB_ptr », voir sources du TP2) :
// Recupère le naming service
CORBA::Object_var obj;
try
{
obj = orb -> resolve_initial_references("NameService");
}
catch(const CORBA::ORB::InvalidName&)
{
cout << "impossible de retrouver le `NameService'" << endl;
return EXIT_FAILURE;
}
CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(obj.);
…
//
// creation d’une implementation
//
Calculator_impl* a1p = new Calculator_impl;
Calculator_var a1 = a1p -> _this();
…
// publie un nom aupres du Naming Service : « mickey »
CosNaming::Name a1Name;
a1Name.length(1);
a1Name[0].id = CORBA::string_dup("mickey");
a1Name[0].kind = CORBA::string_dup("");
nc -> bind(a1Name, a1);
Coté serveur:
Lancer le name service et afficher l'IOR du name service :
nameserv -i -OAport 8001
ou
nameserv.exe -i -IIOPport 1973
Pour utiliser le naming service, il faut passer en argument de votre programme ceci:
-ORBInitRef NameService=corbaloc:iiop:localhost:8001/NameService
par exemple :
server.exe -ORBInitRef NameService=corbaloc:iiop:localhost:1973/NameService
client.exe -ORBInitRef NameService=corbaloc:iiop:localhost:1973/NameService
Cela permet d’indiquer à l’ORB comment retrouver votre annuaire.
Note : sur les versions de Orbacus avant la 4.1.3 il faut egalement faire :
2 creer un fichier pointé par ORBACUS_CONFIG : OBC_ROOT\etc\orbacus.cfg
3 creer une ligne "ooc.service.NameService=" avec l'IOR du naming service du step 1
Modifier le serveur pour qu’il crée 3 instances de servant Calculator, qu’il publiera sous les noms de « mickey », « donald », « picsou ».
Ecrire le client interactif qui propose à l'utilisateur le choix de l'opération à réaliser parmi :
- Set (mémoire)
- Get (mémoire)
- Ajouter
- Soustraire
- Multiplier
- Diviser
- Quitter
On choisira pour symboliser les commandes, « l » (lire), « e » (ecrire), et « + » « - » « * » « / ».
Le client devra retrouver le servant par rapport à son nom, en utilisant le naming service.
Attention : CosNaming.lib est nécessaire en plus dans le projet ou le makefile
Voici un exemple de code permettant de faire accès au Naming service coté client (« orb » étant de type « CORBA::ORB_ptr », voir sources du TP2) :
// Recupère le naming service
CORBA::Object_var obj;
try
{
obj = orb -> resolve_initial_references("NameService");
}
catch(const CORBA::ORB::InvalidName&)
{
cout << "impossible de retrouver le `NameService'" << endl;
return EXIT_FAILURE;
}
CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(obj);
(…)
//
// retrouve un nom grace au Naming Service
//
CosNaming::Name aName;
aName.length(1);
aName[0].id = CORBA::string_dup("mickey");
aName[0].kind = CORBA::string_dup("");
CORBA::Object_var aObj = nc -> resolve(aName);
Calculator_var a = Calculator::_narrow(aObj);
(…)
//
// on peut maintenant faire des appels comme par exemple:
a->memoire(4);
cout << "ajouter: " << a->ajouter(2) << endl;
Dans le client, vous pouvez commencer par mettre en dur le nom du servant (comme ci-dessus avec « mickey »). Puis faites en sorte de demander le nom du servant à utiliser au début du programme client.
Exemple d’interrogation clavier en C++ :
string reponse;
cout << "Entrez le nom de l'objet (mickey par exemple): "<< endl;
fflush(stdin);
cin >> reponse;
Ecrire ou Modifier le client qui parcoure et liste à l’écran tous les noms publiés dans le name service. Utiliser les objets dédiés « CosNaming::BindingList_var” et « CosNaming::BindingIterator_var ».
Exemple de code:
CosNaming::BindingList_var bl;
CosNaming::BindingIterator_var bi;
nc -> list(999999, bl.out(), bi.out());
for(int i = 0 ; i < bl -> length() ; i++) AfficherUnNom(bl[i]);
Note : la méthode AfficherUnNom() est un extrait du cours !
Coté serveur, modifier les servants pour qu’ils affichent sur la console le même nom qui a servi à leur publication auprès du service de nom (cad « mickey », « donald », « picsou »)