Programmation C sharp/Exécution distante
Une application .NET peut être un service distant et peut s'exécuter comme :
Serveur RPC
modifierServeur Remoting
modifierÀ l'aide de la librairie System.Runtime.Remoting
à placer dans l'application servante et cliente, celles-ci peuvent partager une classe par Marshaling suivant un canal Http, Ipc ou Tcp.
Le remoting utilise les échanges RPC.
Dans cette solution :
- INTERFACE : IRemoteMath est une librairie de classe
- SERVER : RemoteServer est une application console
- CLIENT : RemoteClient est une application console
L'interface partagée
modifierUne interface IOperations comprenant un prototype d'addition.
namespace IRemoteMath
{
public interface IOperations
{
int Addition(int a, int b);
}
}
Le serveur
modifierLe serveur est l'application qui distribue ses services. Pour qu'elle déserve à distance, il lui faut :
- Dans ses références :
- System.Runtime.Remoting
- Le namespace d'IRemoteMath
- Implémenter IOperations
Implémenter IOperations
modifierLa classe à servir doit faire partie du service distributeur ici RemoteServer
namespace RemoteServer
{
public class RemoteOperations : MarshalByRefObject, IRemoteMath.IOperations
{
// l'objet aura une durée de vie illimitée
public override object InitializeLifetimeService()
{
return null;
}
// cette méthode sera servie
public int Addition(int a, int b)
{
Console.WriteLine(String.Format("> Addition() : a={0}, b={1}", a, b));
return a + b;
}
}
}
MarshalByRefObject signifie que RemoteOperations fera l'objet d'un marshaling.
Configurer RemoteMain
modifierPour écouter les appels, le serveur doit créer un canal d'écoute sur un port et enregistrer le service à distribuer.
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace RemoteServer
{
class RemoteMain
{
[STAThread]
static void Main(string[] args)
{
try
{
// Création du canal sur le port 1050
TcpChannel channel = new TcpChannel(1050);
// Enregistrement du canal
ChannelServices.RegisterChannel(channel);
// Distribution de l'objet en mode singleton
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemoteOperations),
"RemoteOperations",
WellKnownObjectMode.Singleton);
Console.WriteLine("Serveur démarré");
Console.ReadLine();
}
catch
{
Console.WriteLine("Erreur au démarrage");
Console.ReadLine();
}
}
}
}
- [STAThread] au point d'entrée instruit le main comme "appartement" pour cloisonner les traitements au partage de ses ressources.
- RemotingConfiguration.RegisterWellKnownServiceType enregistre RemoteOperations dans ses services
- Le canal est ici en TCP
Le client
modifierLe client appelle les services. Pour qu'elle soit servie, il lui faut :
- Dans ses références :
- System.Runtime.Remoting
- Le namespace d'IRemoteMath
using System;
using System.Text;
// Remoting
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace RemoteClient
{
class RemoteTestClient
{
// préparation de l'objet distribué
private IRemoteMath.IOperations remoteOperation;
public RemoteTestClient()
{
try
{
// init channel - facultatif
// TcpChannel channel = new TcpChannel();
// ChannelServices.RegisterChannel(channel);
// init IOperations < RemoteServer.RemoteOperations
this.remoteOperation = (IRemoteMath.IOperations)Activator.GetObject(
typeof(IRemoteMath.IOperations),
"tcp://localhost:1050/RemoteOperations");
}
catch {
Console.WriteLine("Erreur de connexion");
}
}
public void RemoteAddition(int a, int b)
{
try
{
if (this.remoteOperation != null)
{
Console.WriteLine("Résultat : " + this.remoteOperation.Addition(a, b).ToString());
}
}
catch
{
Console.WriteLine("Erreur à l'appel");
}
}
[STAThread]
static void Main()
{
RemoteTestClient Client = new RemoteTestClient();
Client.RemoteAddition(15, 20);
System.Threading.Thread.Sleep(5000);
}
}
}
- [STAThread] indique qu'on est dans le même type de cloisonnement des threads que pour server.
- remoteOperation dépile la classe reçu par TCP permettant l'utilisation de ses propriétés.
Application
modifier- Pour effectuer le test, il faut compiler les trois projets IRemoteMath,RemoteServer,RemoteClient
- Executer RemoteServer.exe avant RemoteClient.exe
Le résultat du client devrait être :
Résultat : 35
Le message du serveur devrait être :
> Addition() : a=15, b=20