Programmation C sharp/Exécution distante
Un livre de Wikibooks.
Cette page est considérée comme une ébauche à compléter. Si vous possédez quelques connaissances sur le sujet, vous pouvez les partager en éditant dès à présent cette page (en cliquant sur le lien « modifier »).
Ressources suggérées : Programmation C sharp/Bibliographie et liens
Une application .NET peut être un service distant et peut s'exécuter comme :
Sections |
[modifier] Serveur RPC
[modifier] Serveur Remoting
À 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
[modifier] L'interface partagée
Une interface IOperations comprenant un prototype d'addition.
namespace IRemoteMath { public interface IOperations { int Addition(int a, int b); } }
[modifier] Le serveur
Le 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
[modifier] Implémenter IOperations
La 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.
[modifier] Configurer RemoteMain
Pour é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
[modifier] Le client
Le 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.
[modifier] Application
- 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
